当初FreeBSDのkernelのarmの実装はNetBSDのコードをベースに作られていました。NetBSDのコードはRiscBSDという古いプロジェクトから受け継がれたもののようです。
armは同じチップがarmv6と言われたりarm11x6と言われたりしてとっても混乱します。
FreeBSDでは2014年くらいにarmv6(11x6)からNetBSDの実装から離れて独自実装に切り替えました。そのためv5以前のサポートコードはlocore-v4.Sのようになりv6以降はlocore-v6.Sのようになりました。
いろいろ調べていたら、当初はNetBSDのコードをベースにv6のサポートを入れていたようです。これを消して独自実装に切り替えたようです。
この判断は今となってみると、失敗だったと思われます。
というのは現在FreeBSDはarm.arm,arm.armv6,arm.armv7と三つのアーキテクチャになってしまってます。arm.armv6はv7(CORTEXA)よりもv5に近くv7以降で変更を加えるのが正解だったと思われます。
NetBSDのコードをみるとv6以前とv7で分かれているようです。
NetBSDのソースは取得方法はこちらに記述がありましたが、curlを入れてないので、直接下記のコマンドを叩きました。
% fetch "http://ftp.jaist.ac.jp/pub/NetBSD/NetBSD-8.1/source/sets/syssrc.tgz"
NetBSDのarmのコードのありかはusr/src/sys/arch/arm/armです。
NetBSDから受け継がれたコードはcpufunc_asm_armv5_ec.Sのようにarmのバージョン毎のファイルが定義されていました。
FreeBSDで新しく実装されたファイルはマクロでCPUの設定を行うようになっています。
mcr CP15_TLBIALL /* Flush TLB */
は
# define CP15_TLBIALLIS p15, 0, r0, c8, c3, 0 /*Invalidate entire unified TLB IS */
のように定義されています。
cp15_ifsr_get()は
_RF0(cp15_ifsr_get, CP15_IFSR(%0))
のように定義されていて、
# define _RF0(fname, aname...) \
static __inline uint32_t \
fname(void) \
{ \
uint32_t reg; \
__asm __volatile("mrc\t" _FX(aname): "=r" (reg)); \
return(reg); \
}
となり、
# define CP15_IFSR(rr) p15, 0, rr, c5, c0, 1 /* Instruction Fault Status Register */
となります。
cpu_asm-v6.Sにあるarmv6のアセンブラで、
# if __ARM_ARCH == 6
のような条件があるのですが、そもそもファイル名がv6なので、デフォルトはv6でそれ以外の場合(v7)の条件式にすべきではないでしょうか。
あとcpu_asm-v6.Sの中はマクロだったり直書きだったりして、統一感がまったくありません。
armv6の1136r0には無い(armv6kになるr1にはあるようです)clrex命令がFreeBSDでは直に書かれてしまっていますが、NetBSDではarmv6では使わないような条件が入っています。1176にはあるようなんですが。ここら辺をみるとFreeBSDの実装者がNetBSDの実装者より劣っているのがわかります。とりあえずラズパイの1176で動けばいいというつもりで書いたのではないでしょうか。
v6以外とは現状v7とv8の32Bit版(aarch32)になるようです。armの32Bitは、ほぼこれで終わりと思われます。
v6というのであればまず1136で動くようにするのがOSのサポートの正しい姿勢だと思います。
どうもFreeBSDのv6対応の実装ははやちゃくちゃない(庄内弁)感じがします。
1136なComcerto 1000のために調べているのですが、現状のFreeBSDのコードはNetBSDから受け継がれたarmv5サポートより、1136(v6)の方が怪しい(動かない)状態になっているとようです。
いろいろ考えてみるとFreeBSD側の問題もありますが、armが複雑な製品構成なことも要因な気がします。
armv6をarmv4系に寄せるのが正解な気がしますが、おそらくFreeBSDにはもう力がないので、最終的に両方消すという判断になってしまいそうです。とっても残念です。