APC8750にNetBSD/evbarmを移植するための記録 7/8
2014/07/08(火) 26:48 NetBSD はてブ情報 はてブに登録 はてブ数

5月にはコードの整形やらehciを動かそうとしたりと格闘していたのですが、挫折して放置をしていました。唯一進んだのはapc_machdep.cにapc_system_resetを実装し、リブートできるようになったことぐらいでしょうか。

その辺の記録はさておき、ひさびさに手を付けようかと思いたち新しめのcurrentで動くかなーと軽い気持ちで試してみたら、そもそもコンパイルが通りません。

wmt_intr.cに
#include <arm/cpufunc.h>
を追加したり、wmt_com.cで代入しかしていない変数を削ったり、どうにかこうにかカーネルが作れるようになりました。

いざ、起動してみると、こんな感じで止まります。
switching to new L1 page table @0x68c000... ttbpanic: kernel diagnostic assertion "armreg_ttbcr_read() == __SHIFTIN(1, TTBCR_S_N)" failed: "/usr/src/sys/arch/arm/arm32/arm32_kvminit.c", line 978
なんか、arm32_kvminit.cというARM共通っぽいところでこけています。
    973 #ifdef ARM_MMU_EXTENDED
    974 	/*
    975 	 * TTBCR should have been initialized by the MD start code.
    976 	 */
    977 	KASSERT((armreg_contextidr_read() & 0xff) == 0);
    978 	KASSERT(armreg_ttbcr_read() == __SHIFTIN(1, TTBCR_S_N));
    979 	/*
    980 	 * Disable lookups via TTBR0 until there is an activated pmap.
    981 	 */
    982 	armreg_ttbcr_write(armreg_ttbcr_read() | TTBCR_S_PD0);
    983 	cpu_setttb(l1pt_pa, KERNEL_PID);
    984 	arm_isb();
    985 #else
過去の差分を見てみると、動いていた当時のソースには全く存在しない部分のようです。加えて、ARM_MMU_EXTENDEDというifdefに囲まれていることから、どうもこのあたりが臭そうです。

ARM_MMU_EXTENDEDを定義しているのはsys/arch/arm/include/cpuconf.hの次の部分でしょう。
    232 /*
    233  * Can we use the ASID support in armv6+ MMUs?
    234  */
    235 #if !defined(_LOCORE)
    236 #define	ARM_MMU_EXTENDED	((ARM_MMU_MEMC + ARM_MMU_GENERIC	\
    237 				  + ARM_MMU_SA1 + ARM_MMU_XSCALE	\
    238 				  + ARM_MMU_V6C) == 0			\
    239 				 && (ARM_MMU_V6N + ARM_MMU_V7) > 0)
    240 #if ARM_MMU_EXTENDED == 0
    241 #undef ARM_MMU_EXTENDED
    242 #endif
    243 #endif
つまり、define文の右辺が怪しいなー、という感じです。

一方、ARM_MMU_EXTENDEDで処理を分岐させているカーネルはいくつかあり、armadaxp, imx31あたりのスタートアップルーチンが関係しています。ところが、APCのお手本にしたRPIではARM_MMU_EXTENDEDは関係ないようです。

うーん、じゃぁ、うまくARM_MMU_EXTENDEDから逃げているんだろうなぁ。あるとしたら、configで何かしていないだろうかと思い立ち、evbarm/confの下にあるRPI関連のファイルをあさっていると、std.rpiのコミットログに"Define ARM11_COMPAT_MMU (for now) to keep inline with cpuconf.h changes "という記述がありました。MMUというのがいかにも関係しそうです。

ARM_MMU_EXTENDEDの定義でもコミットログにも出てきたcpuconf.hに戻ってみると、
    209 #if !defined(_KERNEL_OPT) ||						\
    210 	(defined(CPU_ARM11) && defined(ARM11_COMPAT_MMU))
    211 #define	ARM_MMU_V6C		1
    212 #else
    213 #define	ARM_MMU_V6C		0
    214 #endif
    215 
    216 #if !defined(_KERNEL_OPT) ||						\
    217 	(defined(CPU_ARM11) && !defined(ARM11_COMPAT_MMU))
    218 #define	ARM_MMU_V6N		1
    219 #else
    220 #define	ARM_MMU_V6N		0
    221 #endif
なるほど。ARM11_COMPAT_MMUは、いかにもARM_MMU_EXTENDEDの定義に絡みそうな分岐をしています。

ARM11_COMPAT_MMUが定義されると、ARM_MMU_V6C, ARM_MMU_V6Nに影響を与えます。結果として、ARM_MMU_EXTENDEDが0となり、結果としてARM_MMU_EXTENDEDがundefされるようです。

ということで、APCのstd.acpにも
options 	ARM11_COMPAT_MMU
を加え、カーネルを作り直して起動してみました。

見事、起動です!

これで、新しめのcurrentで動くようになりました。

名前:  非公開コメント   

  • TB-URL  http://www.tokuda.net/diary/0847/tb/