FreeBSDは12のリリースに向けてarmの古いコードを消していて私の書いたarm/ralinkも危うく消されそうになって、結構頭にきてます。で、腹いせにというわけではないのですが、PCIのサポートも入れてみました。
かなり前からやってたのですが、手こずってやっと動くようになりました。
このSOCのPCIの構成はこのようになっています。
まずdtsiにpciを追加してfdtでPCIがprobeされるようにします。
PCIのattachではPCIのメモリ空間とIO空間の確保とBridgeの初期化を行います。このSOCのPCI Host Bridge(0,0)はコンフィグレーションのベンダーがabcdでデバイスが1234となっていて、おそらく正式なIDではないと思われます。
Bridgeの初期化はメモリ空間にあるレジスタとコンフィグレーションレジスタでおこないます。この方法は採用されているBridge毎に違います。
レビューのコードを見てもらうと分かりますが、コンフィグレーション読み書きの処理とちょっとした初期化ぐらいしかしていません。PCIはドライバーの処理軽減のためにハードがいろいろやってくれるおかげだと思います。
arm/versatileを参考にしたのですが、このコードのコンフィグレーションの読み書きで0.0は除外するコードが入っています。
これを知らずにBridgeのコンフィグレーションの初期化を行っていたので動きませんでした。
PCIでBrigeのアドレス空間(BAR0)はメインメモリすなわちこのSOCでは0x40000000に設定します。
FreeBSDのPCIバスのプローブのコードはデバイスを対象にしていてHost Bridge(0.0)は対象から外すのがしきたりのようです。このため初期化の時だけ読めるようにして、PCIバスのプローブ時には0xffffを返すようにしました。
PCIでは割り込みの処理も必要なのですが、fdtとpcibがうまくやってくれているようで、自前の処理はありません。
なにか一つPCIのドライバーを書いてみたいと思っていたので、デバイスの処理が動いた時にはちょっと嬉しかったです。
RT1310Aは10年くらい前のSOCですが、このころはSOCにPCIバスがありましたが、その後あまり使われなくなってIOがメモリ空間直付けになり、最近だとハイエンドのSOCでPCI-eをサポートしているケースもちらほらあるようです。
古いarmのコードはfdtやINTRNGやeventtimerなどがサポートされてなかったので、仕方がないところはあるのですが、RT1310Aのコードはこれらを全てサポートしていて、消される言われはこれっぽちもありません。
16MのメモリのターゲットでもFreeBSDはちゃんと動くのですが、中の人はそうは思ってなかったようです。Flashが4Mで動かせるのはZRouterのおかげですが、カーネルはそれほど操作してないので、16Mのメモリで動くのはFreeBSDの実力です。jailは標準で入るですが、このような組み込みではあまり必要ないので、外せるようにするとか、もう少しカーネルを小さくする仕組みがあっても良い気がしますが。
小さいOSとしてFreeBSDを使いたい需要もあるとおもうので、あまり大きくしないポリシーもあっても良いのではないかと思います。
amd64でarmをクロスビルドするとZRouterを使っても7時間以上かかり、素のbuildworld/kernelだとそれ以上かかり気が遠くなります。gcc 4.2のままのmipsは45分くらいです。clangのビルドが大半の時間をしてめていて、もしクロスビルドに時間がかかるからターゲットを絞りたいとか考えているのであれば、そもそもclangにしたこと自体が間違いだったのではないでしょうか。