/* speedstep system management interface port/command. * * These parameters are got from IST-SMI BIOS call. * If user gives it, these are used. *
*/ staticint smi_port; staticint smi_cmd; staticunsignedint smi_sig;
/* info about the processor */ staticenum speedstep_processor speedstep_processor;
/* * There are only two frequency states for each processor. Values * are in kHz for the time being.
*/ staticstruct cpufreq_frequency_table speedstep_freqs[] = {
{0, SPEEDSTEP_HIGH, 0},
{0, SPEEDSTEP_LOW, 0},
{0, 0, CPUFREQ_TABLE_END},
};
/** * speedstep_smi_get_freqs - get SpeedStep preferred & current freq. * @low: the low frequency value is placed here * @high: the high frequency value is placed here * * Only available on later SpeedStep-enabled systems, returns false results or * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing * shows that the latter occurs if !(ist_info.event & 0xFFFF).
*/ staticint speedstep_smi_get_freqs(unsignedint *low, unsignedint *high)
{
u32 command, result = 0, edi, high_mhz, low_mhz, dummy;
u32 state = 0;
u32 function = GET_SPEEDSTEP_FREQS;
if (!(ist_info.event & 0xFFFF)) {
pr_debug("bug #1422 -- can't read freqs from BIOS\n"); return -ENODEV;
}
/* abort if results are obviously incorrect... */ if ((high_mhz + low_mhz) < 600) return -EINVAL;
*high = high_mhz * 1000;
*low = low_mhz * 1000;
return result;
}
/** * speedstep_set_state - set the SpeedStep state * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH) *
*/ staticvoid speedstep_set_state(unsignedint state)
{ unsignedint result = 0, command, new_state, dummy; unsignedlong flags; unsignedint function = SET_SPEEDSTEP_STATE; unsignedint retry = 0;
if (new_state == state)
pr_debug("change to %u MHz succeeded after %u tries " "with result %u\n",
(speedstep_freqs[new_state].frequency / 1000),
retry, result); else
pr_err("change to state %u failed with new_state %u and result %u\n",
state, new_state, result);
return;
}
/** * speedstep_target - set a new CPUFreq policy * @policy: new policy * @index: index of new freq * * Sets a new CPUFreq policy/freq.
*/ staticint speedstep_target(struct cpufreq_policy *policy, unsignedint index)
{
speedstep_set_state(index);
return 0;
}
staticint speedstep_cpu_init(struct cpufreq_policy *policy)
{ int result; unsignedint *low, *high;
/* capability check */ if (policy->cpu != 0) return -ENODEV;
result = speedstep_smi_ownership(); if (result) {
pr_debug("fails in acquiring ownership of a SMI interface.\n"); return -EINVAL;
}
/* detect low and high frequency */
low = &speedstep_freqs[SPEEDSTEP_LOW].frequency;
high = &speedstep_freqs[SPEEDSTEP_HIGH].frequency;
result = speedstep_smi_get_freqs(low, high); if (result) { /* fall back to speedstep_lib.c dection mechanism:
* try both states out */
pr_debug("could not detect low and high frequencies " "by SMI call.\n");
result = speedstep_get_freqs(speedstep_processor,
low, high,
NULL,
&speedstep_set_state);
if (result) {
pr_debug("could not detect two different speeds" " -- aborting.\n"); return result;
} else
pr_debug("workaround worked.\n");
}
/** * speedstep_init - initializes the SpeedStep CPUFreq driver * * Initializes the SpeedStep support. Returns -ENODEV on unsupported * BIOS, -EINVAL on problems during initiatization, and zero on * success.
*/ staticint __init speedstep_init(void)
{ if (!x86_match_cpu(ss_smi_ids)) return -ENODEV;
switch (speedstep_processor) { case SPEEDSTEP_CPU_PIII_T: case SPEEDSTEP_CPU_PIII_C: case SPEEDSTEP_CPU_PIII_C_EARLY: break; default:
speedstep_processor = 0;
}
if (!speedstep_processor) {
pr_debug("No supported Intel CPU detected.\n"); return -ENODEV;
}
MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value " "-- Intel's default setting is 0xb2");
MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value " "-- Intel's default setting is 0x82");
MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the " "SMI interface.");
MODULE_AUTHOR("Hiroshi Miura");
MODULE_DESCRIPTION("Speedstep driver for IST applet SMI interface.");
MODULE_LICENSE("GPL");
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.