bool GeforceSensors::shadowBios() { struct nouveau_device *device = &card; //try to load bios from registry first from "vbios" property created by Chameleon boolloader if (OSData *vbios = OSDynamicCast(OSData, pciDevice->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)) { //nv_info(device, "early shadow VBIOS succeeded\n"); } else { if (device->bios.data && device->bios.size) { IOFree(card.bios.data, card.bios.size); device->bios.data = NULL; device->bios.size = 0; } return false; } } 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; }
static int nouveau_bios_shadow(struct nouveau_bios *bios) { struct methods shadow_methods[] = { #if defined(__powerpc__) { "OpenFirmware", nouveau_bios_shadow_of, true, 0, 0, NULL }, #endif { "PRAMIN", nouveau_bios_shadow_pramin, true, 0, 0, NULL }, { "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL }, { "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL }, { "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL }, { "PLATFORM", nouveau_bios_shadow_platform, true, 0, 0, NULL }, {} }; struct methods *mthd, *best; const struct firmware *fw; const char *optarg; int optlen, ret; char *source; optarg = nouveau_stropt(nv_device(bios)->cfgopt, "NvBios", &optlen); source = optarg ? kstrndup(optarg, optlen, GFP_KERNEL) : NULL; if (source) { /* try to match one of the built-in methods */ mthd = shadow_methods; do { if (strcasecmp(source, mthd->desc)) continue; nv_info(bios, "source: %s\n", mthd->desc); mthd->shadow(bios); mthd->score = nouveau_bios_score(bios, mthd->rw); if (mthd->score) { kfree(source); return 0; } } while ((++mthd)->shadow); /* attempt to load firmware image */ ret = request_firmware(&fw, source, &nv_device(bios)->pdev->dev); if (ret == 0) { bios->size = fw->size; bios->data = kmemdup(fw->data, fw->size, GFP_KERNEL); release_firmware(fw); nv_info(bios, "image: %s\n", source); if (nouveau_bios_score(bios, 1)) { kfree(source); return 0; } kfree(bios->data); bios->data = NULL; } nv_error(bios, "source \'%s\' invalid\n", source); kfree(source); } mthd = shadow_methods; do { nv_info(bios, "checking %s for image...\n", mthd->desc); mthd->shadow(bios); mthd->score = nouveau_bios_score(bios, mthd->rw); mthd->size = bios->size; mthd->data = bios->data; bios->data = NULL; } while (mthd->score != 3 && (++mthd)->shadow); mthd = shadow_methods; best = mthd; do { if (mthd->score > best->score) { kfree(best->data); best = mthd; } } while ((++mthd)->shadow); if (best->score) { nv_info(bios, "using image from %s\n", best->desc); bios->size = best->size; bios->data = best->data; return 0; } nv_error(bios, "unable to locate usable image\n"); return -EINVAL; }
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; }