APIC (その 4)

残り少し。と言いつつエントリの標題が微妙スギ。local APIC の初期化、とかにしとけば (以下略
APIC (その2)で引用した初期化手順の 2 番目の

まだイネーブルになっていない場合は、SVR (スプリアス・ベクタレジスタ) によって APIC をイネーブルにする。
(IA-32 Intel® アーキテクチャ ソフトウェア・デベロッパーズ・マニュアル 下巻より引用)

の部分が以下。

    /*
     * Enable APIC.
     */
    value = apic_read(APIC_SPIV);
    value &= ~APIC_VECTOR_MASK;
    value |= APIC_SPIV_APIC_ENABLED;
    
    /* This bit is reserved on P4/Xeon and should be cleared */
    if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 15))
        value &= ~APIC_SPIV_FOCUS_DISABLED;
    else
        value |= APIC_SPIV_FOCUS_DISABLED;
    value |= SPURIOUS_APIC_VECTOR;
    apic_write_around(APIC_SPIV, value);

最初と最後を見れば分かる通り、APIC_SPIV の値である 0xF0 (0xFEE000F0) のスプリアス割り込みレジスタから値を読み込んで、その値を操作した後に同一レジスタに値を書き込んでいる。
スプリアス割り込みレジスタの更新によって APIC をイネーブルにしているに違いない。ってか、マニュアルの付録 D によると一行でナニな処理を完了してるんですが。(わら
とりあえず上記処理の意味合いを理解すべく調べてみる。

  1. レジスタに設定された値を value に読み込む。
  2. 0 〜 7 ビットを 0 クリア。
  3. 8 ビットを 1 に (APIC を有効に)。
  4. 条件 (別途チェック) によって 9 ビットを設定
  5. ベクタのフィールド (0 〜 7 ビット) に 0xff を設定。
  6. レジスタに value の値を書き込む。

4.の処理についてはマニュアル方面にも註釈あり。

インテル Pentium 4 プロセッサおよびインテル Xeon プロセッサではサポートしていない。

のが 9 ビットとの事にて_フォーカスプロセッサチェック 有効/無効_ビットという名前が付いていた。boot_cpu_data 構造体の x86_vendor と x86 というメンバの使途と上記式の値についてのナニはここではスルーしておきます。(弱
そのまま続けてAPIC (その2)で引用した初期化手順の 3、4 番目も追い掛けてみようか、と思ったのですが、行数短いにも関わらず、すげぇ微妙な意図が裏にありそうな気がするので別エントリにてナニする事に。

追記

local APIC の enable の方法が IA-32 Intel® ソフトウェア・デベロッパーズ・マニュアル 下巻 8.4.3.ローカル APIC の有効化または無効化という項にて記述されている事を備忘録として以下に引用しておく。

ローカル APIC は、次のいずれかの方法で、有効または無効にできる。

  • IA32_APIC_BASE_MSR 内の APIC グローバル有効/無効フラグの使用 (図8-5を参照)
  • スプリアス割り込みベクタレジスタ内の APIC ソフトウェア有効/無効フラグの使用 (図8-22を参照)

(IA-32 Intel® ソフトウェア・デベロッパーズ・マニュアル 下巻 8.4.3.ローカル APIC の有効化または無効化より引用)
こうして見るに上記二つのナニは同列なのか、と思いきや、マニュアルによると MSR の有効/無効フラグをクリアしてしまうと復旧のスベは再起動しかない、との事。