rpi_start.Sを読む (第8回)
2013/11/10(日) 10:24 NetBSD はてブ情報 はてブに登録 はてブ数

前回の終わりに169行目にジャンプしたところから再開します。

今回読むのは以下の部分です。
    169 2:	str	pa, [l1table, va]
    170 	add	va, va, #4
    171 	add	pa, pa, #(L1_S_SIZE)
    172 	adds	n_sec, n_sec, #-1
    173 	bhi	2b
まずは169行目から。
    169 2:	str	pa, [l1table, va]
strはストア命令です。無印なので32ビットストアですね。レジスタpaをアドレス[l1table, va]にストアします。角かっこがいやらしいですね。

[Rn, Rm]はMem[Rn + Rm]ですから、
  *(l1table + va) = pa;
ということになります。Ll1_tableは.word 0x4000の空間でしたね。
    170 	add	va, va, #4
    171 	add	pa, pa, #(L1_S_SIZE)
addは加算ですね。L1_S_SIZEはセクションのサイズ、つまり1MBですから
  va += 4;
  pa += 0x00100000; /* L1_S_SIZEは1M */
となります。

次に進みます。
    172 	adds	n_sec, n_sec, #-1
    173 	bhi	2b
addsのaddは加算命令で、のこりのsはステータスレジスタの更新あり、でしたね。
セクションから1減算し、ゼロでなければラベル2にジャンプする、という処理になりますね。つまり、今回読んでいるソースはn_secでループしているわけですね。

ループを抜けると、再びラベル3の処理に入ります。そして、新しいMMU_INITマクロで設定したva, pa, n_sec, attrを読み込んで、vaとpaを適切に変換して、また、今回読んだループに入るというわけです。二重ループをこうやって実現しているんですね。

しかし、よくわからないのが173行目にあるbhiのhiです。
これは、キャリーフラグが1かつゼロフラグが0である、という意味になります。

キャリーフラグが1とは桁あふれが発生した場合で、ゼロフラグが0とは命令の結果が0でない(0ならフラグは1)である、という意味です。

なるほど、n_secから1を引いたときにゼロになればゼロフラグが1になりそうです。
一方で、キャリーフラグはn_secつまり0x06や0x10からマイナス1されるだけなので、ちっとも桁あふれなど起きなさそうです。

良く考えると、マイナス1を2の補数で表すと全部の桁が1になります。全部の桁が1に対して正の数を足せば、桁あふれが起きそうな気がします。もしかすると、それでキャリーフラグが立つのかもしれません。

だったら、ゼロフラグだけ見ていればよい気もします。すっきりしないなぁ。

すっきりしませんが、今回読んだ部分をCっぽく書いて終わりにしましょう。
do {
  *(l1table + va) = pa;
  va += 4;
  pa += 0x00100000; /* L1_S_SIZEは1M */
} while (--n_sec > 0)

名前:  非公開コメント   

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