EN JA
CPUFREQ(4)
CPUFREQ(4) FreeBSD Kernel Interfaces Manual CPUFREQ(4)

名称

cpufreqCPU 周波数制御フレームワーク

書式

device cpufreq


#include < sys/cpu.h>

int
cpufreq_levels( device_t dev, struct cf_level *levels, int *count);

int
cpufreq_set( device_t dev, const struct cf_level *level, int priority);

int
cpufreq_get( device_t dev, struct cf_level *level);

int
cpufreq_drv_settings( device_t dev, struct cf_setting *sets, int *count);

int
cpufreq_drv_type( device_t dev, int *type);

int
cpufreq_drv_set( device_t dev, const struct cf_setting *set);

int
cpufreq_drv_get( device_t dev, struct cf_setting *set);

解説

cpufreq ドライバは、CPU 周波数制御ドライバに統一されたカーネルとユーザインタフェースを提供します。それは、異なった設定をすべての考えられるレベルの単一のインタフェースとして提供する複数のドライバを結合しています。 sysctl(8) 通して、または、AC ライン状態が rc.conf(5) を通して変化するとき、設定を切り換えるべきであることを /etc/rc.d/power_profile に示すことによって、ユーザは、このインタフェースに直接アクセスすることができます。

SYSCTL 変数

これらの設定は、代わりの設定を要求するカーネルドライバによって上書きされるかもしれません。これが起こるなら、いったん状態が経過すると (例えば、システムは、十分に冷えた)、元の値は、復旧します。 sysctl が上書き状態のために設定することができないなら、それは、 EPERM を返します。

TSC がタイムカウンタ (timecounter) として使用中であるなら、周波数は、変更することはできません。これは、タイムカウンタシステムが、一定のレート (率) があるソースを使用する必要があるからです。タイムカウンタのソースは、 kern.timecounter.hardware sysctl で変えることができます。利用可能なモードは、 kern.timecounter.choice sysctl エントリにあります。

dev.cpu.%d.freq
MHz 単位の現在のアクティブな CPU 周波数。
dev.cpu.%d.freq_levels
CPU (周波数/電源消費) のための現在利用可能なレベル。 MHz とミリワット単位の値があります。
dev.DEVICE.%d.freq_settings
ドライバ (周波数/電源消費) のための現在利用可能な設定。値には、MHz の単位とミリワットがあります。設定がデバッグ目的のためにどのドライバによって提供されているかを理解するために役立ちます。
debug.cpufreq.lowest
ユーザに提供する最も低い MHz 単位の CPU 周波数。この設定も、同じ名前がある調整変数を通してアクセス可能です。これは、いくつかのシステム上で使用不可能であるかもしれないたいへん低いレベルを無効にするため使用することができます。
debug.cpufreq.verbose
冗長なメッセージを印刷 (表示) します。この設定も、同じ名前がある調整変数を通してアクセス可能です。

サポートされたドライバ

次のデバイスドライバは、 cpufreq インタフェースを通して完全な周波数制御を提供します。通常、一度にこれらの 1 つだけがアクティブとなることができます。

acpi_perf
ACPI CPU 性能状態
est
Intel 強化 SpeedStep
ichss
ICH のための Intel SpeedStep
powernow
K7 と K8 のための AMD PowerNow! と Cool'n'Quiet
smist
PIIX4 のための Intel SMI-based SpeedStep

次のデバイスドライバは、相対的な周波数制御を提供して、付加的効果があります:

acpi_throttle
ACPI CPU スロットリング (絞り)
p4tcc
Pentium 4 の熱制御回路

カーネルインタフェース

カーネルコンポーネントは、 cpufreq カーネルインタフェースを通して CPU 周波数を問い合わせて設定することができます。これは、現在利用可能な周波数レベルを得るために cpufreq_levels() を呼び出し、 cpufreq_get() で現在のレベルをチェックして、 cpufreq_set() でリストから新しいものを設定して、 cpufreq デバイスを入手することを必要とします。各レベルは、実際に 1 つ以上の cpufreq ドライバを参照しますが、カーネルコンポーネントは、これを知っている必要はありません。 struct cf_leveltotal_set 要素は、このレベルの周波数と電力に関する概要を提供します。未知または無意味な値は、 CPUFREQ_VAL_UNKNOWN に設定されます。

cpufreq_levels() メソッドは、 cpufreq デバイスと levels の空の配列を取ります。 count 値は、利用可能なレベルの数を設定すべきで、関数が完了した後、返された実際のレベルの数が設定されます。 count が許可されるレベルより多ければ、 E2BIG を返すべきです。

cpufreq_get() メソッドは、 level を格納するための空間へのポインタを取ります。成功して完了した後に、出力は、現在のアクティブレベルとなり、 cpufreq_levels() によって返されたレベルの 1 つと等しくなります。

cpufreq_set() メソッドは、 level へのポインタを取り、それをアクティブにすることを試みます。 priority (すなわち、 CPUFREQ_PRIO_KERN) は、このレベルをアクティブにしている間に、前の設定を上書きするどうかを cpufreq に伝えます。 priority が現在のアクティブレベルより高いなら、そのレベルは、保存され新しいレベルで上書きされます。レベルが既に保存されているなら、新しいレベルは、古い保存されたレベルを上書きしないで設定されます。 cpufreq_set() が NULL level で呼び出されるなら、保存されたレベルは、復旧されます。保存されたレベルがないなら、 cpufreq_set() は、 ENXIO を返します。 priority が現在のアクティブレベルの優先度より低いなら、このメソッドは、 EPERM を返します。

ドライバインタフェース

ハードウェア特有の CPU 周波数制御を提供するカーネルドライバは、 cpufreq ドライバインタフェースを通してそれらの個々の設定をエクスポートします。これは、次のメソッドの実装を必要とします: cpufreq_drv_settings(), cpufreq_drv_type(), cpufreq_drv_set() と cpufreq_drv_get() です。さらに、ドライバは、 cpufreq フレームワークによってこれらのメソッドを呼び出すことができるように CPU デバイスの子供としてデバイスをアタッチしなければなりません。

cpufreq_drv_settings() メソッドは、現在利用可能な設定、それぞれのタイプ struct cf_setting の配列を返します。ドライバは、未知または無意味な値に CPUFREQ_VAL_UNKNOWN を設定するべきです。各設定のために次のすべての要素が返されるべきです:

struct cf_setting { 
 int freq; /* MHz 単位の CPU クロックまたはパーセント */ 
 int volts; /* mV 単位の電圧 */ 
 int power; /* mV 単位の消費電力 */ 
 int lat; /* us 単位の遷移待ち時間 */ 
 device_t dev; /* この設定を提供するドライバ */ 
};

このメソッドへのエントリでは、 count は、返すことができる設定の数を含んでいます。成功して完了するときに、ドライバは、返された設定の実際の数をそれを設定します。ドライバが count が許可されるより多くの設定を提供するなら、それは、 E2BIG を返すべきです。

cpufreq_drv_type() メソッドは、それが提供する CPUFREQ_TYPE_ABSOLUTE または CPUFREQ_TYPE_RELATIVE のいずれかの設定のタイプを示します。さらに、ドライバは、それが提供する設定が他のドライバだけの情報で cpufreq_drv_set() をアクティブなものに渡すことができないなら、 CPUFREQ_FLAG_INFO_ONLY フラグを設定できます。

cpufreq_drv_set() メソッドは、ドライバの設定を取り、それは、アクティブになります。設定が無効であるかまたは現在利用可能でないなら、それは、 EINVAL を返すべきです。

cpufreq_drv_get() メソッドは、現在アクティブなドライバの設定を返します。返された struct cf_setting は、正しく書き込まれたすべての要素を含む cpufreq_drv_set() に渡されるために正当でなければなりません。ドライバが現在の設定を ( cpu_est_clockrate() でそれを見積もることによってさえ) 推論することができないなら、すべての要素を CPUFREQ_VAL_UNKNOWN に設定するべきです。

作者

Nate Lawson Bruno Ducrot は、 powernow ドライバを寄贈しました。

バグ

次のドライバは、まだ cpufreq インタフェースに変換されていません: longrun(4)

CPU とバス周波数変更は、まだ実装されていないことに注意してください。

複数の CPU が周波数制御を提供するとき、それらは、異なったレベルに設定することができません、そして同じ周波数の設定をすべて提供しなければなりません。

March 3, 2006 FreeBSD