bool GPUSensors::start(IOService *provider) { HWSensorsDebugLog("Starting..."); if (!provider || !super::start(provider)) return false; if (!(pciDevice = OSDynamicCast(IOPCIDevice, provider))) { HWSensorsFatalLog("no PCI device"); return false; } if (!(workloop = getWorkLoop())) { HWSensorsFatalLog("failed to obtain workloop"); return false; } if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &GPUSensors::probeEvent)))) { HWSensorsFatalLog("failed to initialize timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { HWSensorsFatalLog("failed to add timer event source into workloop"); timerEventSource->release(); return false; } timerEventSource->setTimeoutMS(500); return true; }
bool SuperIODevice::start(IOService *provider) { if (!super::start(provider)) return false; // Gigabyte mobos usualy use ITE if (OSDictionary *matching = serviceMatching(kFakeSMCService)) { if (IOService *headingProvider = waitForMatchingService(matching, kFakeSMCDefaultWaitTimeout)) { if (OSString *manufacturer = OSDynamicCast(OSString, headingProvider->getProperty(kOEMInfoManufacturer))) { if (manufacturer->isEqualTo("Gigabyte")) { if (!detectITEFamilyChip()) { UInt16 ite_id = id; if (!detectWinbondFamilyChip()) { HWSensorsFatalLog("found unsupported chip! ITE sequence ID=0x%x, Winbond sequence ID=0x%x", ite_id, id); return false; } } } } } OSSafeRelease(matching); } // Other vendors usualy use Winbond family chipsets if (model == 0) { if (!detectWinbondFamilyChip()) { UInt16 wnbnd_id = id; if (!detectITEFamilyChip()) { HWSensorsFatalLog("found unsupported chip! ITE sequence ID=0x%x, Winbond sequence ID=0x%x", id, wnbnd_id); return false; } } } HWSensorsInfoLog("found %s %s on port=0x%x address=0x%x", vendor, superio_get_model_name(model), port, address); char string[128]; snprintf(string, sizeof(string), "%s,%s", vendor, superio_get_model_name(model)); setName(string); //setProperty("name", &string, (UInt32)strlen(string) + 1); setProperty(kSuperIOHWMAddress, address, 16); setProperty(kSuperIOControlPort, port, 8); setProperty(kSuperIOModelValue, model, 16); setProperty(kSuperIOModelName, superio_get_model_name(model)); setProperty(kSuperIOVendorName, vendor); setProperty(kSuperIODeviceID, OSData::withBytes(&id, sizeof(id))); registerService(); return true; }
bool GmaSensors::managedStart(IOService *provider) { IOPhysicalAddress bar = (IOPhysicalAddress)((pciDevice->configRead32(kMCHBAR)) & ~0xf); HWSensorsDebugLog("Fx3100: register space=%08lx", (long unsigned int)bar); if(IOMemoryDescriptor * theDescriptor = IOMemoryDescriptor::withPhysicalAddress (bar, 0x2000, kIODirectionOutIn)) { if ((mmio = theDescriptor->map())) { mmio_base = (volatile UInt8 *)mmio->getVirtualAddress(); /*HWSensorsDebugLog("MCHBAR mapped"); for (int i = 0; i < 0x2f; i += 16) { HWSensorsDebugLog("%04lx: ", (long unsigned int)i+0x1000); for (int j=0; j<16; j += 1) { HWSensorsDebugLog("%02lx ", (long unsigned int)INVID8(i+j+0x1000)); } HWSensorsDebugLog(""); }*/ } else { HWSensorsInfoLog("MCHBAR failed to map"); return false; } } enableExclusiveAccessMode(); //Find card number gpuIndex = takeVacantGPUIndex(); if (gpuIndex < 0) { HWSensorsFatalLog("failed to obtain vacant GPU index"); return false; } char key[5]; snprintf(key, 5, KEY_FORMAT_GPU_PROXIMITY_TEMPERATURE, gpuIndex); if (!addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, 0)) { HWSensorsFatalLog("failed to register temperature sensor"); releaseGPUIndex(gpuIndex); gpuIndex = -1; return false; } disableExclusiveAccessMode(); registerService(); return true; }
bool TZSensors::start(IOService * provider) { if (!super::start(provider)) return false; acpiDevice = (IOACPIPlatformDevice *)provider; if (!acpiDevice) { HWSensorsFatalLog("ACPI device not ready"); return false; } OSObject *object = NULL; if(kIOReturnSuccess == acpiDevice->evaluateObject("_TMP", &object) && object) { for (UInt8 i = 0; i < 0xf; i++) { char key[5]; snprintf(key, 5, KEY_FORMAT_THERMALZONE_TEMPERATURE, i); if (!isKeyHandled(key)) { if (addSensor(key, TYPE_SP78, TYPE_SPXX_SIZE, kFakeSMCTemperatureSensor, 0)) { break; } } } } registerService(); HWSensorsInfoLog("started on %s", acpiDevice->getName()); return true; }
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); }
bool FakeSMC::start(IOService *provider) { if (!super::start(provider)) return false; OSString *vendor = OSDynamicCast(OSString, getProperty(kFakeSMCFirmwareVendor)); int arg_value = 1; if (PE_parse_boot_argn("-fakesmc-force-start", &arg_value, sizeof(arg_value))) { HWSensorsInfoLog("firmware vendor check disabled"); } else if (vendor && vendor->isEqualTo("Apple")) { HWSensorsFatalLog("forbidding start on Apple hardware"); return false; } if (!smcDevice->initAndStart(provider, this)) { HWSensorsInfoLog("failed to initialize SMC device"); return false; } registerService(); // Load keys from NVRAM if (PE_parse_boot_argn("-fakesmc-use-nvram", &arg_value, sizeof(arg_value))) { if (UInt32 count = smcDevice->loadKeysFromNVRAM()) HWSensorsInfoLog("%d key%s loaded from NVRAM", count, count == 1 ? "" : "s"); else HWSensorsInfoLog("NVRAM will be used to store system written keys..."); } return true; }
void SuperIOPlugin::stop(IOService *provider) { if (gpuIndex >= 0) if (!releaseGPUIndex(gpuIndex)) HWSensorsFatalLog("failed to release GPU index"); super::stop(provider); }
bool GPUSensors::start(IOService *provider) { HWSensorsDebugLog("Starting..."); int arg_value = 1; if (PE_parse_boot_argn("-gpusensors-disable", &arg_value, sizeof(arg_value))) { return false; } if (!provider || !super::start(provider)) return false; if (!(pciDevice = OSDynamicCast(IOPCIDevice, provider))) { HWSensorsFatalLog("no PCI device"); return false; } if (!onStartUp(provider)) return false; if (shouldWaitForAccelerator()) { if (!(workloop = getWorkLoop())) { HWSensorsFatalLog("failed to obtain workloop"); return false; } if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &GPUSensors::probeEvent)))) { HWSensorsFatalLog("failed to initialize startup check timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { HWSensorsFatalLog("failed to add startup check timer event source into workloop"); timerEventSource->release(); return false; } timerEventSource->setTimeoutMS(100); } else return managedStart(provider); return true; }
bool FakeSMCKeyStoreUserClient::initWithTask(task_t owningTask, void* securityID, UInt32 type, OSDictionary* properties) { if (super::initWithTask(owningTask, securityID, type, properties)) { keyStore = NULL; return true; } HWSensorsFatalLog("super failed to initialize with task!"); return false; }
bool TZSensors::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()) { OSBoolean* disable = OSDynamicCast(OSBoolean, configuration->getObject("DisableDevice")); if (disable && disable->isTrue()) 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 TZSensors enabled. // // On the ProBook this is the case with both TZSensors and PTIDSensors, although // PTIDSensors can be avoided by using DropSSDT=Yes (because PTID device is in an SSDT) // // And in the case of TZSensors it even happens (intermittently) without kernel cache. IOSleep(1000); OSObject *object = NULL; if(kIOReturnSuccess == acpiDevice->evaluateObject("_TMP", &object) && object) { for (UInt8 i = 0; i < 0xf; i++) { char key[5]; snprintf(key, 5, KEY_FORMAT_THERMALZONE_TEMPERATURE, i); if (!isKeyHandled(key)) { if (addSensor(key, TYPE_SP78, TYPE_SPXX_SIZE, kFakeSMCTemperatureSensor, 0)) { break; } } } } registerService(); HWSensorsInfoLog("started on %s", acpiDevice->getName()); return true; }
bool ACPIProbeUserClient::start(IOService* provider) { if (!super::start(provider)) return false; if (!(acpiProbe = OSDynamicCast(ACPIProbe, provider))) { HWSensorsFatalLog("provider must be ACPIProbe class service!"); return false; } return true; }
bool FakeSMCKeyStoreUserClient::start(IOService* provider) { if (!super::start(provider)) return false; if (!(keyStore = OSDynamicCast(FakeSMCKeyStore, provider))) { HWSensorsFatalLog("provider must be FakeSMCKeyStore class service!"); return false; } return true; }
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; }
IOReturn GPUSensors::probeEvent() { HWSensorsDebugLog("Probe event..."); if (probIsAcceleratorAlreadyLoaded()) { releaseTimerEventSource(timerEventSource); if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &GPUSensors::delayedStartEvent)))) { HWSensorsFatalLog("failed to initialize delayed startup timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { HWSensorsFatalLog("failed to add delayed startup timer event source into workloop"); timerEventSource->release(); return false; } // Wait a little before start timerEventSource->setTimeoutMS(kGPUSensorsAcceleratorDelayTime); } else if (probeCounter++ == (1000.0f / (kGPUSensorsAcceleratorWaitCycle * 45.0f))) { releaseTimerEventSource(timerEventSource); HWSensorsInfoLog("still waiting for IOAccelerator to start..."); onTimeoutExceeded(pciDevice); } else { // if (probeCounter > 0 && !(probeCounter % ((int)(1000.0f / (float)kGPUSensorsAcceleratorWaitCycle) * 15))) // HWSensorsInfoLog("still waiting for accelerator to start..."); timerEventSource->setTimeoutMS(kGPUSensorsAcceleratorWaitCycle); } return kIOReturnSuccess; }
bool FakeSMCKeyStoreUserClient::initWithTask(task_t owningTask, void* securityID, UInt32 type, OSDictionary* properties) { if (!owningTask) { return false; } if (!super::initWithTask(owningTask, securityID, type, properties)) { HWSensorsFatalLog("failed to initialize with task!"); return false; } keyStore = NULL; clientHasAdminPrivilegue = clientHasPrivilege(securityID, kIOClientPrivilegeAdministrator); return true; }
/** * For internal use, do not override * */ bool FakeSMCPlugin::start(IOService *provider) { if (!super::start(provider)) return false; if (OSDictionary *matching = serviceMatching(kFakeSMCKeyStoreService)) { if (!(keyStore = OSDynamicCast(FakeSMCKeyStore, waitForMatchingService(matching, kFakeSMCDefaultWaitTimeout)))) { HWSensorsFatalLog("still waiting for FakeSMCKeyStore..."); return false; } OSSafeRelease(matching); } return true; }
bool FakeSMC::start(IOService *provider) { if (!super::start(provider)) return false; int arg_value = 1; // Check if we have SMC already 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)) { HWSensorsFatalLog("SMC device detected, will not create another one"); return false; } } OSSafeRelease(iterator); } OSSafeRelease(matching); } if (!smcDevice->initAndStart(provider, this)) { HWSensorsInfoLog("failed to initialize SMC device"); return false; } registerService(); // Load keys from NVRAM if (PE_parse_boot_argn("-fakesmc-use-nvram", &arg_value, sizeof(arg_value))) { if (UInt32 count = smcDevice->loadKeysFromNVRAM()) HWSensorsInfoLog("%d key%s loaded from NVRAM", count, count == 1 ? "" : "s"); else HWSensorsInfoLog("NVRAM will be used to store system written keys..."); } return true; }
void RadeonMonitor::free(void) { if (card.mmio) OSSafeRelease(card.mmio); if (card.bios && card.bios_size > 0) { IOFree(card.bios, card.bios_size); card.bios = 0; } if (card.card_index >= 0) { if (!releaseGPUIndex(card.card_index)) HWSensorsFatalLog("failed to release GPU index"); } super::free(); }
void GeforceSensors::stop(IOService * provider) { if (card.mmio) OSSafeRelease(card.mmio); if (card.bios.data) { IOFree(card.bios.data, card.bios.size); card.bios.data = 0; } if (card.card_index >= 0) { if (!releaseGPUIndex(card.card_index)) HWSensorsFatalLog("failed to release GPU index"); } super::stop(provider); }
bool GeforceSensors::startupCheck(IOService *provider) { HWSensorsDebugLog("Initializing..."); struct nouveau_device *device = &card; if ((card.card_index = takeVacantGPUIndex()) < 0) { nv_fatal(device, "failed to take vacant GPU index\n"); return false; } // map device memory if ((device->pcidev = pciDevice)) { device->pcidev->setMemoryEnable(true); if ((device->mmio = device->pcidev->mapDeviceMemoryWithIndex(0))) { nv_debug(device, "memory mapped successfully\n"); } else { nv_fatal(device, "failed to map memory\n"); return false; } } else { HWSensorsFatalLog("(pci%d): [Fatal] failed to assign PCI device", pciDevice->getBusNumber()); return false; } // identify chipset if (!nouveau_identify(device)) { return false; } if (!shadowBios()) { nv_error(device, "early VBIOS shadow failed, will try after accelerator started\n"); } return true; }
bool ACPIProbe::start(IOService * provider) { ACPISensorsDebugLog("starting..."); if (!super::start(provider)) return false; if (!(acpiDevice = OSDynamicCast(IOACPIPlatformDevice, provider))) { ACPISensorsFatalLog("ACPI device not ready"); return false; } methods = OSArray::withCapacity(0); OSNumber *interval = NULL; OSNumber *timeout = NULL; OSBoolean *logging = NULL; OSArray *list = NULL; // Try to load configuration from info.plist first if (OSDictionary *configuration = getConfigurationNode()) { OSBoolean* disable = OSDynamicCast(OSBoolean, configuration->getObject("DisableDevice")); if (disable && disable->isTrue()) return false; interval = OSDynamicCast(OSNumber, configuration->getObject("PollingInterval")); timeout = OSDynamicCast(OSNumber, configuration->getObject("PollingTimeout")); logging = OSDynamicCast(OSBoolean, configuration->getObject("LoggingEnabled")); list = OSDynamicCast(OSArray, configuration->getObject("Methods")); } // Try to load configuration provided by ACPI device else { OSObject *object = NULL; if (kIOReturnSuccess == acpiDevice->evaluateObject("INVL", &object) && object) interval = OSDynamicCast(OSNumber, object); if (kIOReturnSuccess == acpiDevice->evaluateObject("TOUT", &object) && object) timeout = OSDynamicCast(OSNumber, object); if (kIOReturnSuccess == acpiDevice->evaluateObject("LOGG", &object) && object) { if (OSNumber *number = OSDynamicCast(OSNumber, object)) { logging = OSBoolean::withBoolean(number->unsigned8BitValue() == 1); } } if (kIOReturnSuccess == acpiDevice->evaluateObject("LIST", &object) && object) list = OSDynamicCast(OSArray, object); else ACPISensorsErrorLog("polling methods table (LIST) not found"); } if (interval) { pollingInterval = (double)interval->unsigned64BitValue() / (double)1000.0; ACPISensorsInfoLog("polling interval %lld ms", interval->unsigned64BitValue()); if (pollingInterval) { if (timeout) { pollingTimeout = (double)timeout->unsigned64BitValue() / 1000.0; ACPISensorsInfoLog("polling timeout %lld ms", timeout->unsigned64BitValue()); } if (logging) { loggingEnabled = logging->isTrue(); ACPISensorsInfoLog("logging %s", loggingEnabled ? "enabled" : "disabled"); } if (list) { for (unsigned int i = 0; i < list->getCount(); i++) { if (OSString *method = OSDynamicCast(OSString, list->getObject(i))) { if (method->getLength() && kIOReturnSuccess == acpiDevice->validateObject(method->getCStringNoCopy())) { methods->setObject(method); ACPISensorsInfoLog("method \"%s\" registered", method->getCStringNoCopy()); } else ACPISensorsErrorLog("unable to register method \"%s\"", method->getCStringNoCopy()); } } } } else ACPISensorsWarningLog("polling interval is set to zero, driver will be disabled"); } //REVIEW_REHABMAN: just bail if no methods to call... no need to stick around... if (!methods->getCount()) return false; if (methods->getCount()) { // woorkloop if (!(workloop = getWorkLoop())) { HWSensorsFatalLog("Failed to obtain workloop"); return false; } if (!(timerEventSource = IOTimerEventSource::timerEventSource( this, OSMemberFunctionCast(IOTimerEventSource::Action, this, &ACPIProbe::woorkloopTimerEvent)))) { ACPISensorsFatalLog("failed to initialize timer event source"); return false; } if (kIOReturnSuccess != workloop->addEventSource(timerEventSource)) { ACPISensorsFatalLog("failed to add timer event source into workloop"); return false; } timerEventSource->setTimeoutMS(100); //ACPISensorsInfoLog("%d method%s registered", methods->getCount(), methods->getCount() > 1 ? "s" : ""); } registerService(); ACPISensorsInfoLog("started"); return true; }
bool SuperIODevice::start(IOService *provider) { if (!super::start(provider)) return false; /*for (int i = 0; i < 2; i++) { i386_ioport_t port = kSuperIOPorts[i]; winbond_family_enter(port); UInt16 id = superio_listen_port_word(port, kSuperIOChipIDRegister); UInt16 model = 0; UInt8 ldn = 0; const char* vendor = ""; switch (id) { // Fintek case F71858: model = id; ldn = kF71858HardwareMonitorLDN; vendor = "Fintek"; break; case F71862: case F71868A: case F71869: case F71869A: case F71882: case F71889AD: case F71889ED: case F71889F: case F71808E: model = id; ldn = kFintekITEHardwareMonitorLDN; vendor = "Fintek"; break; default: switch (id >> 8) { // Winbond case 0x52: switch (id & 0xff) { case 0x17: case 0x3A: case 0x41: model = W83627HF; ldn = kWinbondHardwareMonitorLDN; vendor = "Winbond"; break; } break; case 0x82: switch (id & 0xf0) { case 0x80: model = W83627THF; ldn = kWinbondHardwareMonitorLDN; vendor = "Winbond"; break; } break; case 0x85: switch (id & 0xff) { case 0x41: model = W83687THF; ldn = kWinbondHardwareMonitorLDN; vendor = "Winbond"; break; } break; case 0x88: switch (id & 0xf0) { case 0x50: case 0x60: model = W83627EHF; ldn = kWinbondHardwareMonitorLDN; vendor = "Winbond"; break; } break; case 0xA0: switch (id & 0xf0) { case 0x20: model = W83627DHG; ldn = kWinbondHardwareMonitorLDN; vendor = "Winbond"; break; } break; case 0xA5: switch (id & 0xf0) { case 0x10: model = W83667HG; ldn = kWinbondHardwareMonitorLDN; vendor = "Winbond"; break; } break; case 0xB0: switch (id & 0xf0) { case 0x70: model = W83627DHGP; ldn = kWinbondHardwareMonitorLDN; vendor = "Winbond"; break; } break; case 0xB3: switch (id & 0xf0) { case 0x50: model = W83667HGB; ldn = kWinbondHardwareMonitorLDN; vendor = "Winbond"; break; } break; // Nuvoton case 0xB4: switch (id & 0xf0) { case 0x70: model = NCT6771F; ldn = kWinbondHardwareMonitorLDN; vendor = "Nuvoton"; break; } break; case 0xC3: switch (id & 0xf0) { case 0x30: model = NCT6776F; ldn = kWinbondHardwareMonitorLDN; vendor = "Nuvoton"; break; } break; case 0xC5: switch (id & 0xf0) { case 0x60: model = NCT6779D; ldn = kWinbondHardwareMonitorLDN; vendor = "Nuvoton"; break; } break; } break; } UInt16 address = 0; UInt16 verify = 0; if (model != 0 && ldn != 0) { superio_select_logical_device(port, ldn); address = superio_listen_port_word(port, kSuperIOBaseAddressRegister); IOSleep(50); verify = superio_listen_port_word(port, kSuperIOBaseAddressRegister); winbond_family_exit(port); if (address != verify) continue; // some Fintek chips have address register offset 0x05 added already if ((address & 0x07) == 0x05) address &= 0xFFF8; if (address < 0x100 || (address & 0xF007) != 0) continue; } else { winbond_family_exit(port); IOSleep(50); // IT87XX can enter only on port 0x2E if (port == 0x2E) { ite_family_enter(port); id = superio_listen_port_word(port, kSuperIOChipIDRegister); ldn = 0; vendor = ""; switch (id) { case IT8512F: case IT8712F: case IT8716F: case IT8718F: case IT8720F: case IT8721F: case IT8726F: case IT8728F: case IT8752F: case IT8771E: case IT8772E: model = id; ldn = kFintekITEHardwareMonitorLDN; vendor = "ITE"; break; } if (model != 0 && ldn != 0) { superio_select_logical_device(port, ldn); address = superio_listen_port_word(port, kSuperIOBaseAddressRegister); IOSleep(50); verify = superio_listen_port_word(port, kSuperIOBaseAddressRegister); ite_family_exit(port); if (address != verify || address < 0x100 || (address & 0xF007) != 0) continue; } else { ite_family_exit(port); continue; } } }*/ // Gigabyte mobos usualy use ITE if (IOService *headingProvider = waitForService(serviceMatching(kFakeSMCService))) { if (OSString *manufacturer = OSDynamicCast(OSString, headingProvider->getProperty(kOEMInfoManufacturer))) { if (manufacturer->isEqualTo("Gigabyte")) { if (!detectITEFamilyChip()) { UInt16 ite_id = id; if (!detectWinbondFamilyChip()) { HWSensorsFatalLog("found unsupported ship ITE sequence ID=0x%x, Winbond sequence ID=0x%x", ite_id, id); return false; } } } } } // Other vendors usualy use Winbond family chipsets if (model == 0) { if (!detectWinbondFamilyChip()) { UInt16 wnbnd_id = id; if (!detectITEFamilyChip()) { HWSensorsFatalLog("found unsupported ship ITE sequence ID=0x%x, Winbond sequence ID=0x%x", id, wnbnd_id); return false; } } } HWSensorsInfoLog("found %s %s on port=0x%x address=0x%x", vendor, superio_get_model_name(model), port, address); char string[128]; snprintf(string, sizeof(string), "%s,%s", vendor, superio_get_model_name(model)); setName(string); //setProperty("name", &string, (UInt32)strlen(string) + 1); setProperty(kSuperIOHWMAddress, address, 16); setProperty(kSuperIOControlPort, port, 8); setProperty(kSuperIOModelValue, model, 16); setProperty(kSuperIOModelName, superio_get_model_name(model)); setProperty(kSuperIOVendorName, vendor); setProperty(kSuperIODeviceID, OSData::withBytes(&id, sizeof(id))); 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 RadeonMonitor::start(IOService * provider) { HWSensorsDebugLog("Starting..."); if (!super::start(provider)) return false; if (!(card.pdev = (IOPCIDevice*)provider)) return false; if (OSData *data = OSDynamicCast(OSData, provider->getProperty("device-id"))) { card.chip_id = *(UInt32*)data->getBytesNoCopy(); } else { HWSensorsFatalLog("device-id property not found"); return false; } card.pdev->setMemoryEnable(true); for (UInt32 i = 0; (card.mmio = card.pdev->mapDeviceMemoryWithIndex(i)); i++) { long unsigned int mmio_base_phys = card.mmio->getPhysicalAddress(); // Make sure we select MMIO registers if (((card.mmio->getLength()) <= 0x00020000) && (mmio_base_phys != 0)) break; } if (!card.mmio) { HWSensorsInfoLog("failed to map device memory"); return false; } card.family = CHIP_FAMILY_UNKNOW; card.int_thermal_type = THERMAL_TYPE_NONE; card.card_index = takeVacantGPUIndex(); if (card.card_index < 0) { radeon_fatal(&card, "failed to obtain vacant GPU index\n"); return false; } RADEONCardInfo *devices = RADEONCards; while (devices->device_id != NULL) { if ((devices->device_id & 0xffff) == (card.chip_id & 0xffff)) { card.family = devices->ChipFamily; card.info.device_id = devices->device_id; card.info.ChipFamily = devices->ChipFamily; card.info.igp = devices->igp; card.info.is_mobility = devices->is_mobility; radeon_info(&card, "found ATI Radeon 0x%04x\n", card.chip_id & 0xffff); break; } devices++; } if (card.family == CHIP_FAMILY_UNKNOW) { radeon_fatal(&card, "unknown card 0x%04x\n", card.chip_id & 0xffff); //return false; } //try to load bios from ATY,bin_image property of GPU registry node if (OSData *vbios = OSDynamicCast(OSData, provider->getProperty("ATY,bin_image"))) { card.bios_size = vbios->getLength(); card.bios = (UInt8*)IOMalloc(vbios->getLength()); memcpy(card.bios, vbios->getBytesNoCopy(), card.bios_size); if (card.bios[0] == 0x55 && card.bios[1] == 0xaa) { radeon_device *rdev = &card; UInt16 tmp = RBIOS16(0x18); if (RBIOS8(tmp + 0x14) == 0x0) { if ((card.bios_header_start = RBIOS16(0x48))) { tmp = card.bios_header_start + 4; if (!memcmp(card.bios + tmp, "ATOM", 4) || !memcmp(card.bios + tmp, "MOTA", 4)) { card.is_atom_bios = true; } else { card.is_atom_bios = false; } radeon_info(&card, "%sBIOS detected\n", card.is_atom_bios ? "ATOM" : "COM"); } } else radeon_error(&card, "not an x86 BIOS ROM, not using\n"); } else radeon_error(&card, "BIOS signature incorrect %x %x\n", card.bios[0], card.bios[1]); } else radeon_error(&card, "unable to locate ATY,bin_image\n"); if (!card.bios_header_start) { // Free memory for bios image if it was allocated if (card.bios && card.bios_size) { IOFree(card.bios, card.bios_size); card.bios = 0; card.bios_size = 0; } } else if (atom_parse(&card)) { radeon_atombios_get_power_modes(&card); } // Use temperature sensor type based on BIOS name if (card.int_thermal_type == THERMAL_TYPE_NONE && card.bios && card.bios_size) { if (!strncasecmp("R600", card.bios_name, 64) || !strncasecmp("RV610", card.bios_name, 64) || !strncasecmp("RV630", card.bios_name, 64) || !strncasecmp("RV620", card.bios_name, 64) || !strncasecmp("RV635", card.bios_name, 64) || !strncasecmp("RV670", card.bios_name, 64) || !strncasecmp("RS780", card.bios_name, 64) || !strncasecmp("RS880", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_RV6XX; } else if (!strncasecmp("RV770", card.bios_name, 64) || !strncasecmp("RV730", card.bios_name, 64) || !strncasecmp("RV710", card.bios_name, 64) || !strncasecmp("RV740", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_RV770; } else if (!strncasecmp("CEDAR", card.bios_name, 64) || !strncasecmp("REDWOOD", card.bios_name, 64) || !strncasecmp("JUNIPER", card.bios_name, 64) || !strncasecmp("CYPRESS", card.bios_name, 64) || !strncasecmp("PALM", card.bios_name, 64) || !strncasecmp("Wrestler", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_EVERGREEN; } else if (!strncasecmp("SUMO", card.bios_name, 64) || !strncasecmp("SUMO2", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_SUMO; } else if (!strncasecmp("ARUBA", card.bios_name, 64) || !strncasecmp("BARTS", card.bios_name, 64) || !strncasecmp("TURKS", card.bios_name, 64) || !strncasecmp("CAICOS", card.bios_name, 64) || !strncasecmp("CAYMAN", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_NI; } else if (!strncasecmp("CAPE VERDE", card.bios_name, 64) || !strncasecmp("PITCAIRN", card.bios_name, 64) || !strncasecmp("TAHITI", card.bios_name, 64)) { card.int_thermal_type = THERMAL_TYPE_SI; } } // Use driver's configuration to resolve temperature sensor type if (card.int_thermal_type == THERMAL_TYPE_NONE) { radeon_info(&card, "using device-id to resolve temperature sensor type\n"); // Enable temperature monitoring switch (card.family) { case CHIP_FAMILY_R600: /* r600 */ case CHIP_FAMILY_RV610: case CHIP_FAMILY_RV630: case CHIP_FAMILY_RV670: case CHIP_FAMILY_RV620: case CHIP_FAMILY_RV635: case CHIP_FAMILY_RS780: case CHIP_FAMILY_RS880: card.int_thermal_type = THERMAL_TYPE_RV6XX; break; case CHIP_FAMILY_RV770: /* r700 */ case CHIP_FAMILY_RV730: case CHIP_FAMILY_RV710: case CHIP_FAMILY_RV740: card.int_thermal_type = THERMAL_TYPE_RV770; break; case CHIP_FAMILY_CEDAR: /* evergreen */ case CHIP_FAMILY_REDWOOD: case CHIP_FAMILY_JUNIPER: case CHIP_FAMILY_CYPRESS: case CHIP_FAMILY_HEMLOCK: case CHIP_FAMILY_PALM: card.int_thermal_type = THERMAL_TYPE_EVERGREEN; break; case CHIP_FAMILY_BARTS: case CHIP_FAMILY_TURKS: case CHIP_FAMILY_CAICOS: case CHIP_FAMILY_CAYMAN: case CHIP_FAMILY_ARUBA: card.int_thermal_type = THERMAL_TYPE_NI; break; case CHIP_FAMILY_SUMO: case CHIP_FAMILY_SUMO2: card.int_thermal_type = THERMAL_TYPE_SUMO; break; case CHIP_FAMILY_TAHITI: case CHIP_FAMILY_PITCAIRN: case CHIP_FAMILY_VERDE: card.int_thermal_type = THERMAL_TYPE_SI; break; // default: // radeon_fatal(&card, "card 0x%04x is unsupported\n", card.chip_id & 0xffff); // return false; } } // Setup temperature sensor if (card.int_thermal_type != THERMAL_TYPE_NONE ) { switch (card.int_thermal_type) { case THERMAL_TYPE_RV6XX: card.get_core_temp = rv6xx_get_temp; radeon_info(&card, "adding rv6xx thermal sensor\n"); break; case THERMAL_TYPE_RV770: card.get_core_temp = rv770_get_temp; radeon_info(&card, "adding rv770 thermal sensor\n"); break; case THERMAL_TYPE_EVERGREEN: case THERMAL_TYPE_NI: card.get_core_temp = evergreen_get_temp; radeon_info(&card, "adding EverGreen thermal sensor\n"); break; case THERMAL_TYPE_SUMO: card.get_core_temp = sumo_get_temp; radeon_info(&card, "adding Sumo thermal sensor\n"); break; case THERMAL_TYPE_SI: card.get_core_temp = si_get_temp; radeon_info(&card, "adding Southern Islands thermal sensor\n"); break; default: radeon_fatal(&card, "card 0x%04x is unsupported\n", card.chip_id & 0xffff); releaseGPUIndex(card.card_index); card.card_index = -1; return false; } } if (card.get_core_temp) { char key[5]; snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, card.card_index); if (!addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, 0)) { //radeon_error(&card, "failed to register temperature sensor for key %s\n", key); radeon_fatal(&card, "failed to register temperature sensor for key %s\n", key); releaseGPUIndex(card.card_index); card.card_index = -1; return false; } } registerService(); 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; }
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; }
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 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 GeforceSensors::start(IOService *provider) { HWSensorsDebugLog("Starting..."); if (!super::start(provider)) return false; struct nouveau_device *device = &card; // map device memory if ((device->pcidev = (IOPCIDevice*)provider)) { device->pcidev->setMemoryEnable(true); if ((device->mmio = device->pcidev->mapDeviceMemoryWithIndex(0))) { nv_debug(device, "memory mapped successfully\n"); } else { HWSensorsFatalLog("failed to map memory"); return false; } } else { HWSensorsFatalLog("failed to assign PCI device"); return false; } card.card_index = -1; if (OSData *multiboard_capable = OSDynamicCast(OSData, provider->getProperty("rm_multiboard_capable"))) { if (0x1 == *((UInt32*)multiboard_capable->getBytesNoCopy())) { if (OSData *board_number = OSDynamicCast(OSData, provider->getProperty("rm_board_number"))) { UInt8 index = *((UInt32*)board_number->getBytesNoCopy()); card.card_index = takeGPUIndex(index); } } } if (card.card_index < 0) card.card_index = takeVacantGPUIndex(); if (card.card_index < 0) { HWSensorsFatalLog("failed to take vacant GPU index"); return false; } // identify chipset if (!nouveau_identify(device)) { releaseGPUIndex(card.card_index); return false; } // shadow and parse bios //try to load bios from registry first from "vbios" property created by Chameleon boolloader if (OSData *vbios = OSDynamicCast(OSData, provider->getProperty("vbios"))) { device->bios.size = vbios->getLength(); device->bios.data = (u8*)IOMalloc(card.bios.size); memcpy(device->bios.data, vbios->getBytesNoCopy(), device->bios.size); } if (!device->bios.data || !device->bios.size || nouveau_bios_score(device, true) < 1) if (!nouveau_bios_shadow(device)) { if (device->bios.data && device->bios.size) { IOFree(card.bios.data, card.bios.size); device->bios.data = NULL; device->bios.size = 0; } nv_fatal(device, "unable to shadow VBIOS\n"); releaseGPUIndex(card.card_index); card.card_index = -1; return false; } nouveau_vbios_init(device); nouveau_bios_parse(device); // initialize funcs and variables if (!nouveau_init(device)) { nv_error(device, "unable to initialize monitoring driver\n"); releaseGPUIndex(card.card_index); card.card_index = -1; return false; } nv_info(device, "chipset: %s (NV%02X) bios: %02x.%02x.%02x.%02x\n", device->cname, device->chipset, device->bios.version.major, device->bios.version.chip, device->bios.version.minor, device->bios.version.micro); if (device->card_type < NV_C0) { // init i2c structures nouveau_i2c_create(device); // setup nouveau i2c sensors nouveau_i2c_probe(device); } // Register sensors char key[5]; if (card.core_temp_get || card.board_temp_get) { nv_debug(device, "registering i2c temperature sensors...\n"); if (card.core_temp_get && card.board_temp_get) { snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, nouveau_temp_core); snprintf(key, 5, KEY_FORMAT_GPU_HEATSINK_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, nouveau_temp_board); } else if (card.core_temp_get) { snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, nouveau_temp_core); } else if (card.board_temp_get) { snprintf(key, 5, KEY_FORMAT_GPU_HEATSINK_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, nouveau_temp_board); } } else if (card.temp_get) { nv_debug(device, "registering temperature sensors...\n"); snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, nouveau_temp_diode); } int arg_value = 1; if (card.clocks_get && !PE_parse_boot_argn("-gpusensors-no-clocks", &arg_value, sizeof(arg_value))) { nv_debug(device, "registering clocks sensors...\n"); if (card.clocks_get(&card, nouveau_clock_core) > 0) { snprintf(key, 5, KEY_FAKESMC_FORMAT_GPU_FREQUENCY, card.card_index); addSensor(key, TYPE_UI32, TYPE_UI32_SIZE, kFakeSMCFrequencySensor, nouveau_clock_core); } // if (card.clocks_get(&card, nouveau_clock_shader) > 0) { // snprintf(key, 5, KEY_FAKESMC_FORMAT_GPU_SHADER_FREQUENCY, card.card_index); // addSensor(key, TYPE_UI32, TYPE_UI32_SIZE, kFakeSMCFrequencySensor, nouveau_clock_shader); // } if (card.clocks_get(&card, nouveau_clock_rop) > 0) { snprintf(key, 5, KEY_FAKESMC_FORMAT_GPU_ROP_FREQUENCY, card.card_index); addSensor(key, TYPE_UI32, TYPE_UI32_SIZE, kFakeSMCFrequencySensor, nouveau_clock_rop); } if (card.clocks_get(&card, nouveau_clock_memory) > 0) { snprintf(key, 5, KEY_FAKESMC_FORMAT_GPU_MEMORY_FREQUENCY, card.card_index); addSensor(key, TYPE_UI32, TYPE_UI32_SIZE, kFakeSMCFrequencySensor, nouveau_clock_memory); } } if (card.fan_pwm_get || card.fan_rpm_get) { nv_debug(device, "registering PWM sensors...\n"); char title[DIAG_FUNCTION_STR_LEN]; snprintf (title, DIAG_FUNCTION_STR_LEN, "GPU %X", card.card_index + 1); if (card.fan_rpm_get && card.fan_rpm_get(device) >= 0) addTachometer(nouveau_fan_rpm, title, GPU_FAN_RPM, card.card_index); if (card.fan_pwm_get && card.fan_pwm_get(device) >= 0) addTachometer(nouveau_fan_pwm, title, GPU_FAN_PWM_CYCLE, card.card_index); } if (card.voltage_get && card.voltage.supported) { nv_debug(device, "registering voltage sensors...\n"); snprintf(key, 5, KEY_FORMAT_GPU_VOLTAGE, card.card_index); addSensor(key, TYPE_FP2E, TYPE_FPXX_SIZE, kFakeSMCVoltageSensor, 0); } registerService(); nv_info(device, "started\n"); 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; }