Example #1
0
/**
 *  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;
}
Example #3
0
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;
}
Example #4
0
/**
 *  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;
}
Example #5
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;
}
Example #6
0
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;
}