bool SuperIOPlugin::addTemperatureSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding temperature sensors..."); for (int i = 0; i < temperatureSensorsLimit(); i++) { char key[8]; snprintf(key, 8, "TEMPIN%X", i); if (OSObject* node = configuration->getObject(key)) { for (int j = 0; j < FakeSMCTemperatureCount; j++) { if (addSensorFromConfigurationNode(node, FakeSMCTemperature[j].name, FakeSMCTemperature[j].key, FakeSMCTemperature[j].type, FakeSMCTemperature[j].size, kFakeSMCTemperatureSensor, i)) break; } if (gpuIndex < 0) gpuIndex = takeVacantGPUIndex(); if (gpuIndex >= 0) { snprintf(key, 5, KEY_FORMAT_GPU_HEATSINK_TEMPERATURE, gpuIndex); if (!addSensorFromConfigurationNode(node, "GPU", key, TYPE_SP78, TYPE_SPXX_SIZE, kFakeSMCTemperatureSensor, i)) { releaseGPUIndex(gpuIndex); gpuIndex = -1; } } } } return true; }
bool SuperIOPlugin::addVoltageSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding voltage sensors..."); for (int i = 0; i < voltageSensorsLimit(); i++) { char key[5]; snprintf(key, 5, "VIN%X", i); if (OSObject* node = configuration->getObject(key)) { for (int j = 0; j < FakeSMCVolatgeCount; j++) { if (addSensorFromConfigurationNode(node, FakeSMCVolatge[j].name, FakeSMCVolatge[j].key, FakeSMCVolatge[j].type, FakeSMCVolatge[j].size, kFakeSMCVoltageSensor, i)) break; } if (gpuIndex < 0) gpuIndex = takeVacantGPUIndex(); if (gpuIndex >= 0) { snprintf(key, 5, KEY_FORMAT_GPU_VOLTAGE, gpuIndex); if (!addSensorFromConfigurationNode(node, "GPU", key, TYPE_FP2E, TYPE_FPXX_SIZE, kFakeSMCVoltageSensor, i)) { releaseGPUIndex(gpuIndex); gpuIndex = -1; } } } } return true; }
bool LPCSensors::addVoltageSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding voltage sensors..."); for (int i = 0; i < voltageSensorsLimit(); i++) { char key[5]; snprintf(key, 5, "VIN%X", i); if (OSObject* node = configuration->getObject(key)) { if (!addSensorFromNode(node, kFakeSMCCategoryVoltage, kFakeSMCVoltageSensor, i)) { if (checkConfigurationNode(configuration, "GPU Core")) { if (gpuIndex < 0) gpuIndex = takeVacantGPUIndex(); else continue; snprintf(key, 5, KEY_FORMAT_GPU_VOLTAGE, gpuIndex); if (!addSensorFromConfigurationNode(node, key, TYPE_FP2E, TYPE_FPXX_SIZE, kFakeSMCVoltageSensor, i)) { releaseGPUIndex(gpuIndex); gpuIndex = -1; } } } } } return true; }
bool LPCSensors::addTemperatureSensors(OSDictionary *configuration) { HWSensorsDebugLog("adding temperature sensors..."); for (int i = 0; i < temperatureSensorsLimit(); i++) { char key[8]; snprintf(key, 8, "TEMPIN%X", i); if (OSObject* node = configuration->getObject(key)) { if (!addSensorFromNode(node, kFakeSMCCategoryTemperature, kFakeSMCTemperatureSensor, i)) { if (checkConfigurationNode(configuration, "GPU Die")) { if (gpuIndex < 0) gpuIndex = takeVacantGPUIndex(); else continue; snprintf(key, 5, KEY_FORMAT_GPU_DIODE_TEMPERATURE, gpuIndex); if (!addSensorFromConfigurationNode(node, key, TYPE_SP78, TYPE_SPXX_SIZE, kFakeSMCTemperatureSensor, i)) { releaseGPUIndex(gpuIndex); gpuIndex = -1; } } } } } 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 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 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 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; }