> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man4/cpufreq.4.md).

# cpufreq.4

`cpufreq` — CPU 频率控制框架

## 名称

`cpufreq`

## 概要

`device cpufreq`

`#include <sys/cpu.h>`

`Ft int Fn cpufreq_levels device_t dev struct cf_level *levels int *count Ft int Fn cpufreq_set device_t dev const struct cf_level *level int priority Ft int Fn cpufreq_get device_t dev struct cf_level *level Ft int Fo cpufreq_drv_settings device_t dev struct cf_setting *sets int *count Fc Ft int Fn cpufreq_drv_type device_t dev int *type Ft int Fn cpufreq_drv_set device_t dev const struct cf_setting *set Ft int Fn cpufreq_drv_get device_t dev struct cf_setting *set`

## 描述

`cpufreq` 驱动为 CPU 频率控制驱动提供统一的内核与用户接口。它将提供不同设置的多个驱动组合为涵盖所有可能级别的单一接口。用户可通过 [sysctl(8)](/man/man8/sysctl.8.md) 直接访问此接口，或通过在 [rc.conf(5)](/man/man5/rc.conf.5.md) 中指示 **/etc/rc.d/power\_profile** 在交流电源状态变化时切换设置。

## sysctl 变量

这些设置可能被请求替代设置的内核驱动所覆盖。如果发生这种情况，一旦该条件消除（例如系统已充分冷却），原始值将被恢复。如果由于覆盖条件导致某个 sysctl 无法设置，它将返回 Er EPERM。

如果 TSC 正作为时间计数器使用且硬件不支持不变 TSC（invariant TSC），则无法更改频率。这是因为时间计数器系统需要使用具有恒定速率的源。（在支持不变 TSC 的硬件上，无论配置的 P 状态如何，TSC 都以 P0 速率运行。）现代硬件大多具有不变 TSC。可使用 `kern.timecounter.hardware` sysctl 更改时间计数器源。可用模式位于 `kern.timecounter.choice` sysctl 条目中。

**`dev.cpu.%d.freq`** 当前活动的 CPU 频率，单位为 MHz。

**`dev.cpu.%d.freq_driver`** 此 CPU 使用的特定 `cpufreq` 驱动。

**`dev.cpu.%d.freq_levels`** CPU 当前可用的级别（频率/功耗）。值以 MHz 和毫瓦为单位。

**`dev.DEVICE.%d.freq_settings`** 驱动当前可用的设置（频率/功耗）。值以 MHz 和毫瓦为单位。这有助于理解哪些设置由哪个驱动提供，便于调试。

**`debug.cpufreq.lowest`** 向用户提供的最低 CPU 频率，单位为 MHz。此设置也可通过同名可调参数访问。可用于禁用在某些系统上可能不可用的极低级别。

**`debug.cpufreq.verbose`** 打印详细消息。此设置也可通过同名可调参数访问。

**`debug.hwpstate_pstate_limit`** 若启用，AMD hwpstate 驱动会将 P 状态的管理控制（包括由 [powerd(8)](/man/man8/powerd.8.md) 进行的控制）限制为 0xc0010061 MSR 中的值，即"PStateCurLim\[CurPstateLimit]"。默认禁用（0）。在某些硬件上，该限制寄存器似乎只是跟随已配置的 P 状态，导致永远无法将 P 状态从降频状态提升回 P0。

## 支持的驱动

以下设备驱动通过 `cpufreq` 接口提供绝对频率控制。通常同一时间只能有一个处于活动状态。

**acpi\_perf** ACPI CPU 性能状态 [**est(4)**](/man/man4/est.4.md) Intel Enhanced SpeedStep **hwpstate** 用于 K10 至 Family 17h 的 AMD Cool'n'Quiet2 [**hwpstate\_intel(4)**](/man/man4/hwpstate_intel.4.md) Intel SpeedShift 驱动 **ichss** 用于 ICH 的 Intel SpeedStep **powernow** 用于 K7 和 K8 的 AMD PowerNow! 和 Cool'n'Quiet **smist** 用于 PIIX4 的基于 Intel SMI 的 SpeedStep

以下设备驱动提供相对频率控制，具有叠加效果：

**acpi\_throttle** ACPI CPU 节流 **p4tcc** Pentium 4 温度控制电路

## 内核接口

内核组件可通过 `cpufreq` 内核接口查询和设置 CPU 频率。这包括获取 `cpufreq` 设备、调用 Fn cpufreq\_levels 获取当前可用的频率级别、使用 Fn cpufreq\_get 检查当前级别，以及从列表中使用 Fn cpufreq\_set 设置新级别。每个级别实际上可能引用多个 `cpufreq` 驱动，但内核组件无需了解这一点。`struct cf_level` 的 `total_set` 元素提供该级别的频率和功率摘要。未知或不相关的值设为 `CPUFREQ_VAL_UNKNOWN`。

Fn cpufreq\_levels 方法接受一个 `cpufreq` 设备和一个空的 `levels` 数组。`count` 值应设为可用的级别数，函数完成后将设为返回的实际级别数。如果级别数多于 `count` 所允许的，应返回 Er E2BIG。

Fn cpufreq\_get 方法接受一个用于存储 `level` 的空间指针。成功完成后，输出将为当前活动级别，等于 Fn cpufreq\_levels 返回的级别之一。

Fn cpufreq\_set 方法接受一个指向 `level` 的指针并尝试激活它。`priority`（例如 `CPUFREQ_PRIO_KERN`）告知 `cpufreq` 在激活此级别时是否覆盖之前的设置。如果 `priority` 高于当前活动级别的优先级，该级别将被保存并以新级别覆盖。如果已保存了某个级别，则设置新级别而不覆盖先前保存的级别。如果调用 Fn cpufreq\_set 时 `level` 为 `NULL`，将恢复已保存的级别。如果没有已保存的级别，Fn cpufreq\_set 将返回 Er ENXIO。如果 `priority` 低于当前活动级别的优先级，此方法返回 Er EPERM。

## 驱动接口

提供硬件特定 CPU 频率控制的内核驱动通过 `cpufreq` 驱动接口导出其各自的设置。这包括实现以下方法：Fn cpufreq\_drv\_settings、Fn cpufreq\_drv\_type、Fn cpufreq\_drv\_set 和 Fn cpufreq\_drv\_get。此外，驱动必须将一个设备附加为 CPU 设备的子设备，以便 `cpufreq` 框架能调用这些方法。

Fn cpufreq\_drv\_settings 方法返回一个当前可用设置的数组，每个设置类型为 `struct cf_setting`。驱动应将未知或不相关的值设为 `CPUFREQ_VAL_UNKNOWN`。每个设置应返回以下所有元素：

```sh
struct cf_setting {
	int	freq;	/* CPU 时钟，单位为 MHz 或百分之一的百分点。 */
	int	volts;	/* 电压，单位为 mV。 */
	int	power;	/* 功耗，单位为 mW。 */
	int	lat;	/* 转换延迟，单位为 us。 */
	device_t dev;	/* 提供此设置的驱动。 */
};
```

进入此方法时，`count` 包含可返回的设置数。成功完成后，驱动将其设为返回的实际设置数。如果驱动提供的设置数多于 `count` 所允许的，应返回 Er E2BIG。

Fn cpufreq\_drv\_type 方法指示其提供的设置类型，为 `CPUFREQ_TYPE_ABSOLUTE` 或 `CPUFREQ_TYPE_RELATIVE`。此外，如果驱动提供的设置仅供其他驱动参考且不能传递给 Fn cpufreq\_drv\_set 来激活，则驱动可设置 `CPUFREQ_FLAG_INFO_ONLY` 标志。

Fn cpufreq\_drv\_set 方法接受一个驱动设置并将其设为活动状态。如果设置无效或当前不可用，应返回 Er EINVAL。

Fn cpufreq\_drv\_get 方法返回当前活动的驱动设置。返回的 `struct cf_setting` 必须可有效地传递给 Fn cpufreq\_drv\_set，包括所有元素均已正确填写。如果驱动无法推断当前设置（即使通过 Fn cpu\_est\_clockrate 估算），则应将所有元素设为 `CPUFREQ_VAL_UNKNOWN`。

## 参见

[acpi(4)](/man/man4/acpi.4.md), [est(4)](/man/man4/est.4.md), [timecounters(4)](/man/man4/timecounters.4.md), [powerd(8)](/man/man8/powerd.8.md), [sysctl(8)](/man/man8/sysctl.8.md)

## 作者

Nate Lawson Bruno Ducrot 为 `powernow` 驱动作出了贡献。

## 缺陷

以下驱动尚未转换为 `cpufreq` 接口：[longrun(4)](https://github.com/FreeBSD-Ask/freebsd-man-sc/blob/main/man4/longrun.4.i386.md)。

CPU 和总线频率变化的通知尚未实现。

当多个 CPU 提供频率控制时，无法将它们设置为不同级别，且必须都提供相同的频率设置。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man4/cpufreq.4.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
