BIOSとマイクロコード

自作パソコンを使っている人であれば、CPUの交換をしたことがあると思います。買おうとしているCPUがマザーボードで使えるかどうかは、マザーボードメーカーのWebサイトで調べることになります。

(本記事の初稿は2004年です。10年以上経過した現在でも有用な内容と思われるので、そのままの内容で公開します。)

■BIOSとマイクロコード
本稿執筆時に使っているマザーボードはAsustekのP4B533-Eです。845E(Brookdale-E)チップセットの古いマザーです。最初に使ったCPUはCeleron1.7GHz(FSB:400MHz, S-Spec:失念, Wilametteコア)で、1年後にCeleron2.4GHz(FSB:400MHz, S-Spec:SL6XG(C1-Stepping), Northwoodコア)に交換し、これからPentium4-3.06GHz(FSB:533MHz, S-Spec:SL6PG(D1-Stepping), Northwoodコア)に交換します。

ASUSのWebサイトを調べると、1011以降のBIOSであればPentium4-3.06GHzに対応していることになっています。今入っているBIOSは1014なので、対応していることになります。でも1014のリリース日は2003年3月になっており、果たしてD1ステッピングのPentium4-3.06GHzに対応しているのかどうかはWebサイトを調べただけではわかりません。

本題に入る前に、CPUのステッピングとBIOSの対応を調べることがなぜ大事なのかを説明します。かつて初期のPentium(60MHz/66MHz/90MHz/100MHz)が、FPU命令のバグ(FDIV, FPREM, FPTAN, FPATAN)でリコール(交換・回収)されたことがありました。新聞で大々的に報じられ、IBMなどの大手メーカーが搭載機の出荷を自粛するなど大騒ぎになりました。(インテルが「トラブルに遭遇する確率は数千年に一回であり、実使用上まったく問題ない」と発表しているにもかかわらず出荷停止措置になるのを見ていて、メーカー側がトラブルに便乗してインテルをいじめているかのような印象を持ちました。)その後、インテルはこれに懲りたのか、CPUのマイクロコードにパッチを当てる仕組みを開発し、PentiumIIの頃から実装しています。(「PentiumIIの頃」という曖昧な表現になっているのは、どの製品から導入したのかが正確にはわからないためです。MMX Pentiumの頃からあるのかもしれません。)

以前「日経バイト」で読んだ記事によると、マイクロコードにパッチを当てる仕組みは、

  • BIOS内部にパッチを保持
  • CPU起動時にステッピングを読み取り、対応したパッチをCPUへ転送
  • パッチそのものは暗号化されている

のようなものだそうです。(この記事を失念してしまった。残念。)パッチがステッピング毎に用意されているのは、CPUのバグはステッピング毎に管理されているからです。エラッタについては、インテルが発行しているエラッタ集に記載されています。(CPUのエラッタが公開されるようになったのはPentiumのFDIVバグ騒動のもたらしてくれた思いがけない(いい)副産物だと思います。これ以前、エラッタ情報はエンドユーザーには非公開でしたから。)

BIOS内部でステッピングを読み取り、パッチを当てているので、CPUとBIOSの対応を調べることが重要になってくるわけです。なおインテル製CPUのステッピングは、Processor Spec Finderで調べられます。

■BIOSを調べる
P4B533-EのBIOSはAward製なので、AwardのBIOSを編集・閲覧できるツールが必要になります。以前はAward社のWebサイトで配布されていたらしいですが、その後中止されたらしく、検索して探し出す必要があります。有名なのはCBROMで、オープンソースのものとしてAwardModがあります。もっと検索していたところ、うるりの物置きで‘MicrocodeViewerを見つけたのでこれを使うことにします。

Pentium4-3.06GHzに対応した最初のBIOSである1011を調べてみます。

こりゃ、駄目です。D1-Stepping(CPUIDは0xF29)用のパッチが入っていません。次に今入っている1014を調べてみます。

CPUIDが0xF29用のパッチが入っています。ついでにベータ版のBIOS(1015.003)を調べます。このBIOSはD1-Stepping以降しか存在していないCeleron2.8GHz(FSB:400MHz, Northwoodコア, Socket478)に対応しています。

1014よりも新しいRevisionのパッチが入っています。BIOSをアップデートして1015.003に入れ替えようかと考えましたが、

  • 1014自体はPentium4-3.06GHzに対応したBIOSである
  • ベータ版のBIOSを使うのは精神衛生上よろしくない

などの理由から、1014のままで使い続けることにしました。

CPUを交換して電源を入れたところ、以下のような画面が表示され、正常に認識されました。Hyper Threading対応のCPUなので、CPU2の表示が出るようになっています。

AwardのBIOSであっても最近のものや、AMIなど他社のBIOSでも上記のようにして調べられるのかどうかはわかりません。

■マイクロコードにパッチをあてる手順

BIOSが持っているCPUID:0F29h用マイクロコードのパッチのRevisionは、0x0Aですが、Windows XP SP2上でwcpuid, CrystalCPUIDを使って調べると0x21になっています。Windowsがパッチをあてているのだろうかと考えて調べてみたところ、マイクロコードにパッチをあてる方法が、インテルが発行しているIA32ソフトウェア・デベロッパーズ・マニュアルの「システム・プログラミング・ガイド」に書いてありました。(手元の版だと、「第8章:プロセッサの管理と初期化」の「8.11 マイクロコード・アップデート機能」)概要はこんな感じです。

  • アップデート用のデータのヘッダーは48バイト
  • アップデート用のデータは暗号化されており、サイズは2000バイトもしくは4バイト単位のサイズ
  • CPUはリアルモード・プロテクトモードのどちらでもよい
  • パッチデータは現在のCPUモードでアクセスできるアドレス空間内のどこに配置してもよい
  • リアルモードでパッチをあてる場合はセグメント境界をまたがないようにパッチデータを配置する
  • EDX:EAXにパッチデータのアドレスを入れ, ECXでMSRを指定した上で、WRMSRを使って書き込む
  • Pentium4の場合、MSRは0x79となる(ECX=79h)

■Linuxでの実例

Linuxではカーネル経由でパッチをあてることができます。

さらにLinuxのカーネル(2.6.8)のソースを調べてみたところ、ありました。パッチデータを読み込み、検証した上で、WRMSRを使って書き込んでいます。以下に引用します。

The Linux Kernel Archives

■Windowsでは?
あまり情報がありませんが、サポート情報から推測するなら、WindowsXP/Windows Server 2003以降であれば、Linux同様にマイクロコードにパッチをあてる仕組みをWindows自身が持っていると考えていいでしょう。デバイスマネージャーでプロセッサを見ると、CPU用にドライバーファイルがロードされているのがわかりますが、おそらくこのドライバー内でパッチをあてているのではと推測されます。それ以前のもの(Windows95/98/Me/NT/2000など)については、たぶん実装されていないものと思われます。

■FreeBSDでは?
FreeBSDにもLinux同様の仕組みがないかと気になり、FreeBSD4.8とFreeBSD5.3-beta5の両方のカーネルのソース(/usr/src/sys/i386)を調べてみましたが、見つけられませんでした。ないんでしょうか?FreeBSDファンなので、ちょっとがっかり。

■AMD製CPUでは?

AMDのK8(Athlon64/Opteronなど)にもマイクロコードにパッチをあてる仕組みがあるらしいです。これを使うとBIOSに内蔵してシステムの起動時にパッチをあてることも、OS上からパッチをあてることもできます。その詳細が解明されてしまっています。手順としてはMSRを使って書き込むものですが、どうもパッチデータが暗号化されていないらしいです。

(2005/10/29追記)「Revision Guide for AMD Athlon64 and AMD Opteron Processors」(Revision 3.57, August 2005)によると、マイクロコードにパッチをあてる際に使うMSRはC001_0020hのようです。ただパッチをあてる詳細手順はわかりません。(AMD64のマニュアルに記載がない。)

起草日:2004年9月18日(土)(www.marbacka.net内の別のサイトで公開)
最終更新日:2017年2月19日(日)

スポンサーリンク