はじめに
Linuxの本家Mainline Kernelにも組み込まれているFPGAをコンフィグレーションするための FPGA subsystemについて書かせていただきます。主にARM CPUを内蔵するFPGAをLinuxで動作させている時に使うものです。デバイスツリーオーバーレイの仕組みを使い、このSubsystemのFPGA regionをオーバーレイすることによりFPGAのコンフィグレーションが行えます。
Partial Reconfigurationの対応まで考えられた仕組みですが、とりあえずここでは、FPGA全体をコンフィグレーションする場合を中心に書いております。
ご参考まで:
デバイスツリーについて調べてみた 、
デバイスツリー Overlay について調べてみた
構成要素と動作の仕組み
FPGA Subsystemは、次の3つのframeworkで構成されています。
-
FPGA region
FPGA Manager, FPGA bridgeを使いFPGAのコンフィグレーションを行います。FPGAの書き換え中にCPU側に変な信号(spurious signals)が送られないようにし、安全に再コンフィグレーションが行える仕組みになっています(FPGA bridge を disable にする -> FPGA Manager でコンフィグする -> FPGA bridge を enable にする、という動作)。コンフィグレーションの動作は、オーバーレイにて指定されたpropertyによりコントロールされます。 -
FPGA Manager
FPGAのコンフィグレーションコントローラ。ここにビットストリームを送り込むことでコンフィグレーションが行われる。FPGAの状態もここで管理される。 -
FPGA bridge
書き換えらるFPGA部 とCPU側 を接続するバスブリッジ。実装によっては、不要な場合もあり(FPGA Managerが必要なFPGA Bridgeの動作ケアをしている場合。X系のフルFPGAコンフィグレーション)。
Partial Reconfigurationの場合は、FPGA内のソフトロジックで作られたものになるかと思います。
FPGAコンフィグをするために必要なデバイスツリー記述
FPGA subsystemを使ってFPGAをコンフィグレーションするためのデバイスツリー記述について書きます。
Base Tree において
少なくとも以下のnodeがBase Device tree(起動時に読み込まれるデバイスツリー)に入っている必要があります。
-
FPGA Manager node
FPGAのコンフィグレーションコントローラ。compatible property は使うFPGA用のドライバようの文字列を使う: X系なら "xlnx,zynq-devcfg-1.0", I系なら"altr,socfpga-fpga-mgr"。 -
FPGA region node
Base tree中の最上位のFPGA regionは、Base FPGA regionと呼ばれ、FPGA全体を表すnodeとなります。このFPGA regionのpropertyには、fpga-mgr = <FPGA Managerへのphandle>;
が書かれていることが必要です。もし、Partial reconfigに対応するなら、Base FPGA region の子nodeとしてさらにFPGA region node を作り、Partial reconfig regionとします。 compatible property は "fpga-region"。 -
FPGA bridge node
これは必要に応じて(FPGAの種類による)。FPGA bridgeは、FPGA regionの親nodeとするか、FPGA regionのpropertyに入れることで、FPGA regionの制御対象となります。
fpga_mgr: fpga-mgr@ff706000 {
compatible = "altr,socfpga-fpga-mgr";
...
};
fpga_bridge0: fpga-bridge@ff400000 {
compatible = "altr,socfpga-lwhps2fpga-bridge";
...
};
base_fpga_region0: base-fpga-region0 {
compatible = "fpga-region";
fpga-mgr = <&fpga_mgr>;
};
Overlay において
デバイスツリー オーバーレイファイルにおいて、以下の記述をするとコンフィグレーションが実行できます。ルート直下のnodeにおいて、以下のproperty, nodeを記述します。
-
"target-path" もしくは "target" プロパティ
オーバーレイをするターゲットのnodeとしてBase treeに存在しているFPGA region node を指定する。target-path
ではフルパス名を指定、target
では、phandle を指定する -
"__overlay__" node
オーバレイの仕組みに従い、オーバーレイする内容(property, nodes)をこのnode下に書く。以下の内容は、この __overlay__ node の下に書く。 -
"firmware-name" プロパティ:
コンフィグレーションファイル名を指定する。指定したコンフィグレーションファイルは、/lib/firmware/ に置いておく。このプロパティがあると、オーバーレイ実行時にFPGAコンフィグレーションが行われる。
なお、オーバーレイ削除時には、制御対象となっている fpga-bridge は disable される( -> 結果 FPGA アクセスはできなくなる)。 -
"external-fpga-config" プロパティ:
FPGA のコンフィグレーションを行わない場合は、firmware-name プロパティを指定する代わりにこのプロパティを記述しておく。 -
#address-cells, #size-cells, ranges プロパティ :
アドレスマッピングをする子nodeを持つ場合には必要。 -
子nodeたち :
オプション。コンフィグレーションしたことにより、あらたに追加されたハードウェアのためのnodeを記述。(別のnodeの下に追加しても良い)
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&base_fpga_region0>;
...
__overlay__ {
firmware-name = "soc_system.rbf";
...
};
};
};
参考資料
Kernel Source Tree の Documentation/devicetree/bindings/fpga/fpga-region.txt
https://www.kernel.org/doc/html/latest/driver-api/fpga/index.html
https://elinux.org/images/8/88/Fpga_and_dt.pdf
Solution Zynq PL Programming With FPGA Manager
Linux Kernel 4.10 でのFPGAのサポート事情