mipsのアセンブラ


Broadcomのmips SOCで動かしているmrubyはメモリ8M固定でStack Pointer(SP)を8Mの位置に設定して動作していました。これは8Mしかメモリがない機種があったためにそうしました。16Mのメモリをつんでいる機種では8Mが使えない状態でした。

しかしせっかくなので、メモリ量を考慮してSPを設定できるようにしたいと考えました。

物理メモリ量はブートローダーのCFEのAPIを使うと取得できます。しかしCFEのAPIはcなので、SPを最初に設定しているスタートアップのアセンブラコードでは利用できません。

スタートアップのアセンブラコードでは一旦8MでSPを設定して、呼び出されたcコードで、APIを利用してメモリ量を取得して、8Mより大きい場合はSPを移動するようにしてみました。この処理はcでは書けないのでアセンブラで書きました。

mipsのアセンブラはいろいろな大学で課題になっていてgoogleで検索するといろいろ出てきますが、最初にあった岡山大学の以下のページを参考にしました。

cコードに入っているのでStackはすで使用さているので、使用されているStackをコピーしてSPを移動する処理をします。

relocsp:
        move    $8, $sp
        li      $9, 0x80800000
        move    $10, $sp
        add     $10, $10, $4
2:      lw      $11, 0($8)
        sw      $11, 0($10)
        add     $8, 4
        add     $10, 4
        blt     $8,$9,2b
        add     $sp, $sp, $4
        move    $2, $sp
        j       $ra

cコードからは以下のように呼び出します。返り値で変更されたSPが渡されます。

        cfe_getfwinfo(&fwinfo);
        tomem = fwinfo.fwi_totalmem;
     sp = relocsp(tomem - 0x800000);

アセンブラはもう少し簡潔に書けそうな気もするのですが、私はこれしか書けません。

アセンブラ -> c -> mrubyのように処理が流れてmrubyのコードが終了すると c -> アセンブラになり、現在のアセンブラコードは無限ループに入ります。この処理が正常に動いているのでStackは正常と考えられます。