AHCI奮闘記 - 初期化編
こんにちは、突撃隊です。 最近いじっているAHCIというデバイスについて、な、な、なんと 初期化 が無事終了したので知見を共有したいと思います。
AHCIとはなんぞや
Advanced Host Controller Interface(AHCI)とは、SATAのデバイスコントローラです。 SATAをいい感じに触るためのインターフェースを提供してくれます。
初期化の手順について
しっかり初期化をしないとほとんど使い物にならないかもしれません。 ちゃんと仕様書を読んでしっかり初期化をしましょう。
仕様書の該当箇所
AHCI Specification ver 1.3 では、 10.1.2 System Software Specific Initialization にソフトウェアプログラマがやるべき初期化が書かれています。
初期化手順をまとめた
自分なりにやるべき処理をまとめました。
初期化処理メモ(上から順番)
- 最初にリセットをしたほうがいいかもしれない
- PIレジスタを見て実装されているポートを探す
- 以下の処理はすべて実装されているポートにのみ対して行う
- ソフトウェア側でPxCMD.STを0にセットしハードウェアがPxCMD.CRを0にするのを待つ
- 最低500msくらいは待つ
- (PxCMD.FREが1だった場合、これを0にしてハードウェアがPxCMD.FRを0にするのを待つ(最低500ms))
- CAP.NCSを読んで対応スロットを探す
- 各対応スロットにおいて、PxCLBとPxFBのぶんのメモリを確保して0で埋める
- PxFBのメモリ領域を確保した後、PxCMD.FREを1にする
- 各対応スロットに対して、PxSERRをクリアする。ビットに'1s'を書き込んでクリアする
- PxISをクリアした後、IS.IPSをクリアする(順番が重要)
- PxIEレジスタをenableにする。またGHC.IEも1にセットする
(必要なら追加の初期化をする、その際の注意)
自分の自作OSではどうなっているか
QEMU上で動かしています。
初期化直後は以下のようなフラグの状態です。 多分正常だと思います。
status of Generic Host Control cap: 0x00000000c0141f05 ghc: 0x0000000080000002 is: 0x0000000000000000 pi: 0x000000000000003f vs: 0x0000000000010000 ccc_ctl: 0x0000000000000000 ccc_pts: 0x0000000000000000 em_loc: 0x0000000000000000 em_ctl: 0x0000000000000000 cap2: 0x0000000000000000 bohc: 0x0000000000000000 status of HBA Port 0 clb: 0x0000000010000000 clbu: 0x0000000000000000 fb: 0x0000000010008000 fbu: 0x0000000000000000 is: 0x0000000000000000 ie: 0x00000000fdc000ff cmd: 0x0000000000004016 tfd: 0x0000000000000130 sig: 0x0000000000000101 ssts: 0x0000000000000113 sctl: 0x0000000000000000 serr: 0x0000000000000000 sact: 0x0000000000000000 ci: 0x0000000000000000 sntf: 0x0000000000000000 fbs: 0x0000000000000000
なぐり書きなので
また随時更新します。