Everything
8.2.1 ハードウェア向けの初期化ルーチン

ハードウェア向けの初期化処理は次の要素で構成されます。

サンプルではboot.asmに配置しています。

 

(1)

RESETベクタ

マイクロコントローラのリセット時に各PE(プロセッサ・エレメント)のプログラム・カウンタが分岐してくるアドレスに,PEごとのエントリ・ポイント・アドレスへの分岐命令を配置します。RESETベクタのアドレスを保持するRBASEレジスタが512バイト単位で値を保持するため,RESETベクタの先頭は512バイトに整列します。

サンプルではRESET_PEnセクションに配置しています。

    .section "RESET_PE1", text
    .align   512
    jr32     __start ; RESET
    .align   16
    jr32     _Dummy  ; SYSERR
      :
    .align   16
    jr32     _Dummy_EI ; INTn(priority15)

 

セクション名は任意に変更可能ですが,最適化リンカの-startオプションと連動して変更する必要があります。

-start=RESET_PE1/01000000

注意

RESET ベクタのアドレスはデバイスのユーザーズマニュアルを参照してください。

 

各PEのリセット時の分岐先が同一のアドレスである場合,1つのRESET_PEnセクションを各PEで共有して使用します。

 

(2)

割り込みハンドラ・テーブル

拡張仕様(テーブル参照方式)の例外ハンドラ・アドレスを使用する場合,使用する例外ハンドラ・ルーチンのアドレスを本テーブルの対応する要素位置に配置します。テーブル・アドレスを保持するINTBPレジスタが512バイト単位で値を保持するため,テーブルの先頭は512バイトに整列します。

サンプルではEIINTTBL_PEnセクションに配置しています。

    .section "EIINTTBL_PE1", const
    .align   512
    .dw      #_Dummy_EI ; INT0
    .dw      #_Dummy_EI ; INT1
    .dw      #_Dummy_EI ; INT2
    .rept    512 - 3
    .dw      #_Dummy_EI ; INTn
    .endm

注意

テーブルの最大要素数はデバイスのユーザーズマニュアルを参照してください。

 

セクション名は任意に変更可能ですが,スタートアップ内のINTBPレジスタ設定処理と連動して変更する必要があります。

    mov     #__sEIINTTBL_PE1, r10
    ldsr    r10, 4, 1       ; set INTBP

 

(3)

例外ハンドラ・ルーチン

FE,EI各レベルの例外ハンドラ・ルーチンのサンプルです。 何もせず自分自身への分岐を繰り返します。

通常は,Cソース記述で#pragma interruptを用いて用意します。

    .align   2
_Dummy:
    br      _Dummy
_Dummy_EI:
    br      _Dummy_EI

 

(4)

エントリ・ポイント

リセット時にRESETベクタから分岐してくるラベル(アドレス)です。

    .align   2
    .public  __start
__start:

 

(5)

汎用レジスタの初期化

ロックステップ機能を使用する準備として,各PEの汎用レジスタと,EIPC,CTPC,FPEPCレジスタを初期化します。

    $nowarning
    mov     r0, r1
    $warning
    mov     r0, r2
    mov     r0, r3
     :
    mov     r0, r31
    ldsr    r0, 0, 0        ;  EIPC
    ldsr    r0, 16, 0       ;  CTPC

FPEPCはFPUを有効にした後でなければ初期化できないため,後で初期化します。詳細は「FPUの初期設定」を参照してください。

 

(6)

各PE用の初期化処理への分岐

各PEが共通に実行する処理です。自分自身のPEID(プロセッサ・エレメント番号)値を読み出し,その値から各PEごとに用意された初期化処理へ分岐します。

    stsr    0, r10, 2       ; get HTCFG0
    shr     16, r10         ; get PEID
    cmp     1, r10
    bz      .L.entry_PE1
    cmp     2, r10
    bz      .L.entry_PE2
     :
    cmp     7, r10
    bz      .L.entry_PE7

シングルコア用のプログラムではこの処理は不要です。

 

(7)

__exitルーチン

使用しないPEを待機させておくための,自分自身への分岐を繰り返すのみのルーチンです。

__exit:
    br      __exit

 

(8)

各PE用の初期化処理

各PE用に用意したハードウェア初期化処理(_hdwinit_PEn)と,例外ハンドラ・アドレスの拡張仕様(テーブル参照方式)を使用するための設定処理(_set_table_reference_method)を呼び出し,ユーザ・プログラム向けの初期化ルーチン(_cstart_pmn)へ分岐します。

.L.entry_PE1:
    jarl    _hdwinit_PE1, lp        ; initialize hardware
    mov     #__sEIINTTBL_PE1, r6
    jar     _set_table_reference_method, lp ; set table reference method
    jr32    __cstart_pm1

 

(9)

ハードウェア初期化処理

サンプルではECC機能を使用するための準備として,RAM領域を初期化します。PE1用の初期化処理でGlobal RAMとLocal RAM(PE1用)を,PE2用の初期化処理でLocal RAM(PE2用)を初期化します。

    .align  2
_hdwinit_PE1:
    mov     lp, r29                 ; save return address
    ; clear Global RAM
    mov     GLOBAL_RAM_ADDR, r6
    mov     GLOBAL_RAM_END, r7
    jarl    _zeroclr4, lp
    ; clear Local RAM PE1
    mov     LOCAL_RAM_PE1_ADDR, r6
    mov     LOCAL_RAM_PE1_END, r7
    jarl    _zeroclr4, lp
    mov     r29, lp
    jmp     [lp]
 
    .align  2
_hdwinit_PE2:
    mov     lp, r29                 ; save return address
    ; clear Local RAM PE2
    mov     LOCAL_RAM_PE2_ADDR, r6
    mov     LOCAL_RAM_PE2_END, r7
    jarl    _zeroclr4, lp
    mov     r29, lp
    jmp     [lp]
 
    .align  2
_zeroclr4:
    br      .L.zeroclr4.2
.L.zeroclr4.1:
    st.w    r0, [r6]
    add     4, r6
.L.zeroclr4.2:
    cmp     r6, r7
    bh      .L.zeroclr4.1
    jmp     [lp]

注意

サンプルでは無効なアドレスをマクロで指定しています。初期化対象のRAMアドレスはデバイスのユーザーズマニュアルを参照してください。

 

(10)

例外ハンドラ・アドレスの拡張仕様(テーブル参照方式)を使用するための設定処理

INTBPレジスタへの割り込みハンドラ・テーブルのアドレスの設定と,割り込み制御レジスタの設定を行います。

    .align  2
_set_table_reference_method:
    ldsr    r6, 4, 1        ; set INTBP
    mov     ICBASE, r10     ; get interrupt control register address
    set1    6, 0[r10]       ; set INT0 as table reference
    set1    6, 2[r10]       ; set INT1 as table reference
    set1    6, 4[r10]       ; set INT2 as table reference
    jmp     [lp]