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 GeforceSensors::start(IOService * provider) { DebugLog("Starting..."); if (!super::start(provider)) return false; if (!(fakeSMC = waitForService(serviceMatching(kFakeSMCDeviceService)))) { WarningLog("Can't locate fake SMC device, kext will not load"); return false; } struct nouveau_device *device = &card; //Find card number card.card_index = getVacantGPUIndex(); if (card.card_index < 0) { nv_error(device, "failed to obtain vacant GPU index\n"); return false; } // map device memory // device->pcidev = (IOPCIDevice*)provider; if (device->pcidev) { device->pcidev->setMemoryEnable(true); if ((device->mmio = device->pcidev->mapDeviceMemoryWithIndex(0))) { nv_debug(device, "memory mapped successfully\n"); } else { nv_error(device, "failed to map memory\n"); return false; } } else { nv_error(device, "failed to assign PCI device\n"); return false; } // identify chipset if (!nouveau_identify(device)) 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_error(device, "unable to shadow VBIOS\n"); 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"); return false; } nv_info(device, "chipset: %s (NV%02X) bios: %02x.%02x.%02x.%02x\n", device->cname, (unsigned int)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); this->addSensor(key, TYPE_SP78, 2, 0); snprintf(key, 5, KEY_FORMAT_GPU_HEATSINK_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, 0); } else if (card.core_temp_get) { snprintf(key, 5, KEY_FORMAT_GPU_PROXIMITY_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, 0); } else if (card.board_temp_get) { snprintf(key, 5, KEY_FORMAT_GPU_PROXIMITY_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, 0); } } else if (card.temp_get) { nv_debug(device, "registering temperature sensors...\n"); snprintf(key, 5, KEY_FORMAT_GPU_PROXIMITY_TEMPERATURE, card.card_index); addSensor(key, TYPE_SP78, 2, 0); } if (card.clocks_get) { 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, 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, 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, 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, nouveau_clock_memory); } } if (card.fan_pwm_get || card.fan_rpm_get) { nv_debug(device, "registering PWM sensors...\n"); if (card.fan_rpm_get && card.fan_rpm_get(device) > 0) { char title[6]; snprintf (title, 6, "GPU %X", card.card_index + 1); UInt8 fanIndex = 0; if (addTachometer( fanIndex)) { if (card.fan_pwm_get && card.fan_pwm_get(device) > 0) { snprintf(key, 5, KEY_FAKESMC_FORMAT_GPUPWM, fanIndex); addSensor(key, TYPE_UI8, TYPE_UI8_SIZE, 0); } } } } 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, 0); } nv_info(device, "started\n"); return true; }