[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(toppers-users 1353) Re: jsp-1.4 armv4 のstart.S について



小南と申します。
ARMには全然詳しくなくて、TOPPERSのARM依存部も野口さんのメールを見た後初めて見たのですが、いくつか気がついた点を推測を交えて書きます。
分っている方のフォローをお願いします。


On Fri, 23 Jan 2004 11:38:12 +0900
bartok at bb-west ne jp wrote:

> 初めて質問を送らせていただきます。野口と申します。
> 
> jsp-1.4 の config/armv4/start.S に関しての質問です。
> stub 未使用時 irq が発生した場合 irq_vector アドレスにジャンプすると
> 思うのですが
> 
> irq_vector:
>         .long   irq_exception
> 
> となっており IRQ_Handler は呼ばれていません。

** Cut quoted 21 lines by the mail filter. **

config/armv4/start.Sでは確かにirq_vectorにirq_exceptionが設定されて
います。
しかしsample1.cを実行させるとIRQ_Handlerが呼ばれる、またstart.Sで
irq_exception->IRQ_Handlerにしても動作が変らないということですので、ベクターテーブル
の書換えがかなり初期化のかなり早い段階で行なわれているのではないかと推測されます。
そこでIRQ_Handlerをconfig/armv4でfindとgrepで検索してみると、以下の箇所が見つかりました。

find . | xargs grep -n "IRQ_Handler"
./excalibur/sys_config.c:73:    arm_install_handler(IRQ_Number,IRQ_Handler);
./excalibur/sys_config.c:139:    stub_set_inh(inhno,IRQ_Handler);
./excalibur/sys_config.h:116:extern void IRQ_Handler(void);
./excalibur/sys_support.S:255:        .global IRQ_Handler
./excalibur/sys_support.S:256:IRQ_Handler:

sys_support.S、sys_config.hはIRQ_Handlerの定義、宣言ですので今は関係ないです。
またsysconfig.c:139はgdbのstubを有効にする場合に呼び出されるため、ここも関係ありません。
そのためsys_config.c:73で書換えが行なわれているのではないかと考えられます。

ここを見てみるとターゲットシステム依存の初期化を行なうsys_initialize()であり、
以下のように、ベクタテーブルにIRQ_Handlerを登録するとコメントが書いてあります。

    /*
     *  ARMのベクタテーブルへ割込みハンドラを登録
     */
    arm_install_handler(IRQ_Number,IRQ_Handler);
   
そこでarm_install_handlerを探してみてみると,cpu_config.hで定義されていました。

Inline void
arm_install_handler(EXCNO excno, FP exchdr)
{
    *arm_vector_add[excno] = (UW)exchdr;
}
 
テーブルらしきarm_vector_addの配列の要素が持つアドレスの示す先にIRQ_Handlerのアドレスを設定しているようです。
arm_vecotr_addは、cpu_config.cにて定義されています。

/*
 * 例外ベクタに書き込まれたジャンプ命令が参照するアドレス
 *
 */
UW *arm_vector_add[8];
 
しかしこの配列を操作して実際にベクタテーブルを書換えたことになるのかが、まだ分りません。
そこでこの配列を初期化しているところを探します。
これはconfig_cpu.cのプロセッサ依存の初期化を行なうvoid cpu_initialize()
で行なわれます。


void
cpu_initialize()
{
                                                                                
    UW i,vector_value;
                                                                                
        interrupt_count = 1;
                                                                                
    /*
     * 例外ベクタに登録されている命令から参照されるアドレスと,
     *そのアドレスの内容(ハンドラの実行先)を保存する.
     */
    for(i = 0; i <=7; i++){
        vector_value = *(volatile UW *)(i*4);
        vector_value &= 0x00000fff;
        arm_vector_add[i] =  (UW *)(vector_value + 8) + i;
        arm_handler_add[i] = *(arm_vector_add[i]);
    }
}

この部分の特に (UW *)(vector_value + 8) + i が理解できないので以下は推測ですが、
例外ベクタを通して、呼び出される関数へのアドレスを格納する領域のアドレスが配列arm_vecotr_addに
格納されるのでしょう(多分)。

以上の推測が正しければ、kernel/startup.cのカーネルの初期化を行なうkernel_start
が以下の通りですので、カーネル初期化の初めに例外ベクタの書換えが行なわれることになります。
デバッガをつかう場合は(カーネル初期化時にも対応できるように)あらかじめIRQ_Handlerを設定しておくが、
そうでなければカーネル初期化時に設定するので構わないということでしょうか。ただしこれも推測です。詳しい方のフォローをお願いします。

void
kernel_start()
{
        /*
         *  ターゲット依存の初期化
         */
        cpu_initialize();
        sys_initialize();
 

----------- 
小南 靖雄
ykominami at nifty com
(NBC00224 at nifty com)