Skip to content
uchan-nos edited this page May 17, 2016 · 15 revisions

AHCI (Advanced Host Controller Interface) についてのメモ書き

2016/05/05 by uchan

メモのスコープ

最終的に SATA ディスクを制御することを目標に、しかし知的好奇心が満たされるよう、最短経路よりは少し豊富な情報を提供する。 AHCI デバイスのメモリ空間、FIS の種類と構造、ATA コマンドの送受信方法、ATA コマンドの種類などを扱う。

SATA ディスクを読み書きするまでの道のり

  1. AHCI デバイスを発見する
    • ベースクラス 01h、サブクラス 06h の PCI デバイスを探す
  2. 各メモリマップを設定する
    • Command List や Received FIS 等のメモリ領域を設定する
  3. SATA デバイスを探す
    • 何番ポートにどんなディスクが接続されているか、されていないか
  4. READ DMA コマンドを準備する
    • Command List 上に READ DMA コマンドを構築する
  5. コマンドを送信する
    • PxCI レジスタのコマンドスロット番号に対応するビットに 1 を書く
    • 事前に PxCMD.ST を 1 にセットしておく必要がある
  6. 割り込みを待ってデータを受け取る
    • 割り込みを有効にしておけば、すべてのコマンドのやり取りが終わった後で割り込まれる
    • 割り込み後、PRDT に設定したメモリ領域にデータが格納されている

ABAR: AHCI デバイスのメモリ空間

AHCI の機能は PCI デバイスとして実装される。そのため、もちろん PCI コンフィグレーションレジスタを持つ。6 本ある 32 ビット BAR のうち、最後の 1 本(オフセット 24h)が AHCI の制御に使われる BAR である。これを ABAR (AHCI Base Address Register) と呼ぶ。

他の BAR はオプショナルであり AHCI には関係ない。AHCI に対応しない古いソフトウェアをサポートするため、IDE コントローラを実装するのに使われたりする。

すべての BAR は BIOS や UEFI が適切な値を設定しているはずなので、自作 OS 側では何も設定する必要はない。cf) PCI Memo

ABAR で指される領域に AHCI コントローラ(HBA: Host Bus Adapter)を制御するレジスタ群がある。さらにその中にもアドレスを格納するレジスタがあり、いろいろなメモリ領域が数珠つなぎになっている。その様子を図示する。

AHCI Memory MapFull Size

HBA Memory Registers

AHCI コントローラを制御するためのレジスタ群である。PCI コンフィギュレーション空間にある ABAR によってメモリにマップしてアクセスする。32 ビット幅のレジスタの集合。

HBA Memory Registers は大きく Generic Host Control レジスタと Port Control レジスタに分かれる。前者は名前の通り AHCI コントローラ全体に影響するレジスタだ。後者は同じ構造のレジスタが SATA ポートごとに一組用意されている。規格上は最大 32 ポートまで扱えるが、実際に使える数は AHCI コントローラに依存する。

Offset 00h: CAP - HBA Capabilities

この HBA が持つ能力を示すためのレジスタ。64 ビットアドレッシングが可能か(ビット 31)とか、ネイティブなコマンドキューをサポートしているか(ビット 30)など、ビットごとに各機能のサポート状況を示す。

ビット 18 はこの HBA が AHCI モードだけをサポートしていることを示す。1 なら AHCI モードのみ、0 ならレガシーモードもサポートする。

ビット 4:0 はこの HBA のシリコンチップがサポートする SATA ポートの最大数-1 を表す。0h なら 1 ポートだけサポートする。1fh なら 32 ポートをサポートする。どんな HBA も最低 1 ポートはサポートしなくてはならない。

Offset 04h: GHC - Global HBA Control

HBA のグローバルな設定などを行うレジスタ。

ビット 31 は HBA の動作モードを取得または設定する。1 なら AHCI モード、0 ならレガシーモード(IDE モード)。レガシーモードをサポートしない HBA の場合、リードオンリーで 1 固定。

ビット 1 は割り込みが有効であることを示す。1 なら有効。

ビット 0 はリセット用ビット。1 を書くと内部リセットが発生し、データ転送およびキューイングに関するすべての状態が初期化される。

Offset 0Ch: PI - Ports Implemented

ソフトウェアから使えるポート(実装されたポート)に対応するビットが 1 となる、リードオンリーなレジスタ。1 の個数は CAP.NP+1 を超えてはいけないが、それより少ないことはあり得る。

Port Registers

ポート毎に存在するレジスタ群。レジスタ名の「x」にはポート番号 0 から 31 が入る。

Offset 00h: PxCLB - Port x Command List Base Address

Command List という構造体が置かれているメモリ領域を指すレジスタ。物理メモリアドレスを格納する。その領域は 1K バイトにアラインされている必要があるので、ビット 9:0 は 0 固定。

64 ビットアドレッシングがサポートされている場合、上位 32 ビットは Offset 04h にある PxCLBU レジスタに格納する。

Offset 08h: PxFB - Port x FIS Base Address

Received FIS という構造体が置かれているメモリ領域を指すレジスタ。物理メモリアドレスを格納する。その領域は 256 バイトにアラインされている必要があるので、ビット 7:0 は 0 固定。

64 ビットアドレッシングがサポートされている場合、上位 32 ビットは Offset 0Ch にある PxFBU レジスタに格納する。

Command List

Command List はその名の通り、複数のコマンドを格納するリストである。SATA ディスクは内部にコマンドキューを持っていて、読み書き命令の実行順を最適化する機能を持つ。それに合わせ、HBA にもコマンドリストがある。

コマンドリストは最大 32 個のコマンドを格納できる。

Received FIS

Clone this wiki locally