/* ignore_ppc: *-1->cpufreqlowleveldriversnotinitialized->_PSS,etc.notcalledyet *ignore_PPC *0->cpufreqlowleveldriversinitialized->consider_PPCvalues *1->ignore_PPCtotally->forcedbyuserthroughbootparam
*/ staticint ignore_ppc = -1;
module_param(ignore_ppc, int, 0644);
MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \ "limited by BIOS, this should help");
staticbool acpi_processor_ppc_in_use;
staticint acpi_processor_get_platform_limit(struct acpi_processor *pr)
{
acpi_status status = 0; unsignedlonglong ppc = 0;
s32 qos_value; int index; int ret;
if (!pr) return -EINVAL;
/* *_PPCindicatesthemaximumstatecurrentlysupportedbytheplatform *(e.g.0=states0..n;1=states1..n;etc.
*/
status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc); if (status != AE_NOT_FOUND) {
acpi_processor_ppc_in_use = true;
if (ACPI_FAILURE(status)) {
acpi_evaluation_failure_warn(pr->handle, "_PPC", status); return -ENODEV;
}
}
index = ppc;
if (pr->performance_platform_limit == index ||
ppc >= pr->performance->state_count) return0;
pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
index, index ? "is" : "is not");
pr->performance_platform_limit = index;
if (unlikely(!freq_qos_request_active(&pr->perflib_req))) return0;
ret = freq_qos_add_request(&policy->constraints,
&pr->perflib_req, FREQ_QOS_MAX,
FREQ_QOS_MAX_DEFAULT_VALUE); if (ret < 0)
pr_err("Failed to add freq constraint for CPU%d (%d)\n",
cpu, ret);
if (!pr->performance) continue;
ret = acpi_processor_get_platform_limit(pr); if (ret)
pr_err("Failed to update freq constraint for CPU%d (%d)\n",
cpu, ret);
}
}
/* *CheckthatACPI'su64MHzwillbevalidasu32KHzincpufreq
*/ if (!px->core_frequency ||
(u32)(px->core_frequency * 1000) != px->core_frequency * 1000) {
pr_err(FW_BUG "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n",
pr->id, px->core_frequency); if (last_invalid == -1)
last_invalid = i;
} else { if (last_invalid != -1) { /* *Copythisvalidentryoverlast_invalidentry
*/
memcpy(&(pr->performance->states[last_invalid]),
px, sizeof(struct acpi_processor_px));
++last_invalid;
}
}
}
if (last_invalid == 0) {
pr_err(FW_BUG "No valid BIOS _PSS frequency found for processor %d\n", pr->id);
result = -EFAULT;
kfree(pr->performance->states);
pr->performance->states = NULL;
}
if (last_invalid > 0)
pr->performance->state_count = last_invalid;
end:
kfree(buffer.pointer);
return result;
}
int acpi_processor_get_performance_info(struct acpi_processor *pr)
{ int result = 0;
if (!pr || !pr->performance || !pr->handle) return -EINVAL;
if (!acpi_has_method(pr->handle, "_PCT")) {
acpi_handle_debug(pr->handle, "ACPI-based processor performance control unavailable\n"); return -ENODEV;
}
result = acpi_processor_get_performance_control(pr); if (result) goto update_bios;
result = acpi_processor_get_performance_states(pr); if (result) goto update_bios;
/* We need to call _PPC once when cpufreq starts */ if (ignore_ppc != 1)
result = acpi_processor_get_platform_limit(pr);
return result;
/* *Having_PPCbutmissingfrequencies(_PSS,_PCT)isaverygoodhintthat *theBIOSisolderthantheCPUanddoesnotknowitsfrequencies
*/
update_bios: if (acpi_has_method(pr->handle, "_PPC")) { if(boot_cpu_has(X86_FEATURE_EST))
pr_warn(FW_BUG "BIOS needs update for CPU " "frequency support\n");
} return result;
}
EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info);
int acpi_processor_pstate_control(void)
{
acpi_status status;
if (!acpi_gbl_FADT.smi_command || !acpi_gbl_FADT.pstate_control) return0;
pr_debug("Writing pstate_control [0x%x] to smi_command [0x%x]\n",
acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command);
status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
(u32)acpi_gbl_FADT.pstate_control, 8); if (ACPI_SUCCESS(status)) return1;
pr_warn("Failed to write pstate_control [0x%x] to smi_command [0x%x]: %s\n",
acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command,
acpi_format_exception(status)); return -EIO;
}
int acpi_processor_notify_smm(struct module *calling_module)
{ staticint is_done; int result = 0;
if (!acpi_processor_cpufreq_init) return -EBUSY;
if (!try_module_get(calling_module)) return -EINVAL;
/* *is_doneissettonegativeifanerroroccursandto1ifnoerror *occurrs,butSMMhasbeennotifiedalready.Thisavoidsrepeated *notificationwhichmightleadtounexpectedresults.
*/ if (is_done != 0) { if (is_done < 0)
result = is_done;
goto out_put;
}
result = acpi_processor_pstate_control(); if (result <= 0) { if (result) {
is_done = result;
} else {
pr_debug("No SMI port or pstate_control\n");
is_done = 1;
} goto out_put;
}
is_done = 1; /* *Success.Ifthere_PPC,unloadingthecpufreqdriverwouldberisky, *sodisallowitinthatcase.
*/ if (acpi_processor_ppc_in_use) return0;
/* Assume no coordination on any error parsing domain info */ if (retval) {
cpumask_clear(pr->performance->shared_cpu_map);
cpumask_set_cpu(i, pr->performance->shared_cpu_map);
pr->performance->shared_type = CPUFREQ_SHARED_TYPE_NONE;
}
pr->performance = NULL; /* Will be set for real in register */
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.