Time Base Registers

お仕事で、あるデバイスの駆動時間計測処理にて、時折なぜか計測時間が 0 になる、という不具合報告がありました。

コードを読んでみると、この処理、インラインアセンブラで どこぞの時間値を取得し、計測終了時間から開始時間を引き算している、というもの。取得値がどうも 20秒程度の周期で 1巡していて、そのため 計測開始時間と終了時間の大小関係が逆転してしまい、それを「0秒」として扱うエラー処理が入っていたから、というのが原因でした。

具体的にどの時間をとってきてるのよ、というわけで、

__asm__("mftb %0" : "=r" (ulOldClk) : );

うにゅ、"mftb" というニモニック、何かな〜と思って 調べてみたら、PowerPC にある Time Base Register の下位32bit をとってくる命令のようです。

Time Base Register って?というと、一定の周期でその値がインクリメントされるレジスタだそうで、猫のターゲットCPU では、クロック毎にカウントアップしているとのこと。32bit の 200MHz ですから、4294967296 / (200 * 1000000) で、21.47484 ≒ 20 秒。なるほど。

ところで、Time Base 値 本来64bit長なのですが、それを 32bit レジスタ ×2 に格納しています。64bit あれば カウンタが一巡するのに ざっと29世紀程 掛かりますので、それが仕様と言い切ってしまえば、ま、いっか。

upper値は "mftbu" というニモニックで取得できます。(桁上がりに注意)

参考サイト