/** * Synchronized method to add a new key to FakeSMCKeyStore and set its handler to the plugin * * @param abbreviation Human readable key abbreviation used in config file * @param category Category (enum kFakeSMCCategory) key belongs to so abbreviation can be checked against the list from specified category only * @param group Key group * @param index Key index not related to key position in FakeSMCKeyStore key list * @param reference Reference modifier value * @param gain Gain modifier value * @param offset Offset modifier value * * @return new FakeSMCSensor object or NULL otherwise */ FakeSMCSensor *FakeSMCPlugin::addSensorUsingAbbreviation(const char *abbreviation, FakeSMCSensorCategory category, UInt32 group, UInt32 index, float reference, float gain, float offset) { LOCK; FakeSMCSensor *sensor = NULL; if (abbreviation && strlen(abbreviation) >= 3) { for (int i = 0; FakeSMCSensorDefinitions[i].name; i++) { FakeSMCSensorDefinitionEntry entry = FakeSMCSensorDefinitions[i]; if (entry.category == category && 0 == strcasecmp(entry.name, abbreviation)) { if (entry.count) { for (int counter = 0; counter < entry.count; counter++) { char key[5]; snprintf(key, 5, entry.key, entry.shift + counter); if (!isKeyExists(key)) { sensor = addSensorForKey(key, entry.type, entry.size, group, index, reference, gain, offset); break; } } } else { sensor = addSensorForKey(entry.key, entry.type, entry.size, group, index, reference, gain, offset); } } } } UNLOCK; return sensor; }
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; }
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; } } //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 (!addSensorForKey(key, TYPE_SP78, 2, kFakeSMCTemperatureSensor, 0)) { HWSensorsFatalLog("failed to register temperature sensor"); releaseGPUIndex(gpuIndex); gpuIndex = -1; return false; } registerService(); return true; }
/** * Synchronized method to add tachometer sensor type into FakeSMCKeyStore. This will update fan counter key. * * @param index Key index not related to key position in FakeSMCKeyStore key list * @param name SMC fan name string up to 12 bytes long * @param type SMC fan type * @param zone SMC fan zone * @param location SMC fan location * @param fanIndex SMC fan index is returned on success * * @return new FakeSMCSensor object or NULL otherwise */ FakeSMCSensor *FakeSMCPlugin::addTachometer(UInt32 index, const char *name, FanType type, UInt8 zone, FanLocationType location, SInt8 *fanIndex) { LOCK; SInt8 vacantFanIndex = keyStore->takeVacantFanIndex(); if (vacantFanIndex >= 0) { char key[5]; snprintf(key, 5, KEY_FORMAT_FAN_SPEED, vacantFanIndex); if (FakeSMCSensor *sensor = addSensorForKey(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; UNLOCK; return sensor; } else HWSensorsErrorLog("failed to add tachometer sensor for key %s", key); } else HWSensorsErrorLog("failed to take vacant Fan index"); UNLOCK; return 0; }
bool GeforceSensors::managedStart(IOService *provider) { HWSensorsDebugLog("Starting..."); struct nouveau_device *device = &card; if (!device->bios.data || !device->bios.size) { if (!shadowBios()) { 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) { snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, card.card_index); addSensorForKey(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); addSensorForKey(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); addSensorForKey(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); addSensorForKey(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); addSensorForKey(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); addSensorForKey(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(&card) >= 0) addTachometer(nouveau_fan_rpm, title, GPU_FAN_RPM, card.card_index); if (card.fan_pwm_get && card.fan_pwm_get(&card) >= 0) addTachometer(nouveau_fan_pwm, title, GPU_FAN_PWM_CYCLE, card.card_index); } if (card.volt.get && card.volt.get(&card) >= 0/*card.voltage_get && card.voltage.supported*/) { nv_debug(device, "registering voltage sensors...\n"); snprintf(key, 5, KEY_FORMAT_GPU_VOLTAGE, card.card_index); addSensorForKey(key, TYPE_FP2E, TYPE_FPXX_SIZE, kFakeSMCVoltageSensor, 0); } registerService(); nv_info(device, "started\n"); return true; }
bool RadeonSensors::managedStart(IOService *provider) { if (!(card.pdev = pciDevice)) { HWSensorsFatalLog("failed to assign PCI device"); return false; } if ((card.card_index = takeVacantGPUIndex()) < 0) { radeon_info(&card, "failed to take GPU index\n"); return false; } if (OSData *data = OSDynamicCast(OSData, provider->getProperty("device-id"))) { card.chip_id = *(UInt32*)data->getBytesNoCopy(); } else { radeon_fatal(&card, "device-id property not found"); return false; } card.pdev->setMemoryEnable(true); // IOMemoryMap *mmio; // // for (UInt32 i = 0; (mmio = card.pdev->mapDeviceMemoryWithIndex(i)); i++) { // long unsigned int mmio_base_phys = mmio->getPhysicalAddress(); // // Make sure we select MMIO registers // if (((mmio->getLength()) <= 0x00040000) && (mmio_base_phys != 0)) { // card.mmio = mmio; // break; // } // } card.mmio = card.pdev->mapDeviceMemoryWithIndex(1); if (!card.mmio || 0 == card.mmio->getPhysicalAddress()) { HWSensorsInfoLog("failed to map device memory"); return false; } card.family = CHIP_FAMILY_UNKNOW; card.int_thermal_type = THERMAL_TYPE_NONE; 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; 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, card.pdev->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); } radeon_info(&card, "found ATI Radeon ID: 0x%04x, %s BIOS: %s\n", card.chip_id & 0xffff, card.bios && card.bios_size ? card.is_atom_bios ? "ATOM" : "COM" : "", card.bios && card.bios_size ? card.bios_name : "undefined"); // 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) || !strncasecmp("OLAND", card.bios_name, 64) || !strncasecmp("HAINAN", 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: case CHIP_FAMILY_OLAND: case CHIP_FAMILY_HAINAN: card.int_thermal_type = THERMAL_TYPE_SI; break; case CHIP_FAMILY_BONAIRE: case CHIP_FAMILY_HAWAII: card.int_thermal_type = THERMAL_TYPE_CI; break; case CHIP_FAMILY_KAVERI: case CHIP_FAMILY_KABINI: card.int_thermal_type = THERMAL_TYPE_KV; break; } } // 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; case THERMAL_TYPE_CI: card.get_core_temp = ci_get_temp; radeon_info(&card, "adding Sea Islands (CI) thermal sensor\n"); break; case THERMAL_TYPE_KV: card.get_core_temp = kv_get_temp; radeon_info(&card, "adding Sea Islands (Kaveri) 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; } } char key[5]; if (card.get_core_temp) { char key[5]; snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, card.card_index); if (!addSensorForKey(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(); radeon_info(&card, "started\n"); return true; }