TOPPERS Confidential TOPPERSプロジェクト ディスカッションメモ 処理単位の実行開始/リターン時のシステム状態 作成者: 高田広章(名古屋大学) 最終更新: 2007年7月17日 ○メモの位置付け このメモは,TOPPERS新世代カーネルにおける処理単位の実行開始/リターン時 のシステム状態に関する仕様と,TOPPERS/ASPカーネルにおいてそれがどのよう に実現されているかを記述したものである. ○処理単位の実行開始/リターン時のシステム状態 TOPPERS新世代カーネルにおける処理単位の実行開始/リターン時のシステム状 態について,μITRON4.0仕様より強く規定する.規定の内容については, TOPPERS新世代カーネル仕様書「2.5.12 処理単位とシステム状態」を参照する こと. ●参考:μITRON4.0/PX仕様 CPUロック/ 割込み優先度 ディスパッチ タスク例外 ロック解除状態 マスク 禁止/許可状態 禁止/許可状態 ------------------------------------------------------------------------------ 【タスク】 実行開始条件 解除 - 許可 - 実行開始時処理 そのまま - そのまま 禁止する 終了前 解除 - 許可 任意 終了時処理 未規定(*1) - 未規定(*1)   - ------------------------------------------------------------------------------ 【タスク例外処理ルーチン】 実行開始条件 解除 - 任意 許可 実行開始時処理 そのまま - そのまま 禁止する リターン前 解除 - 任意(*3) 任意 リターン時処理 未規定(*1) - そのまま 許可する ------------------------------------------------------------------------------ 【割込みハンドラ】 実行開始条件 解除 - 任意 任意 実行開始時処理 実装依存 - そのまま そのまま リターン前 実装定義(*2) - 元に戻す(*4) 変更不可 リターン時処理 未規定(*2) - 未規定(*1) そのまま ------------------------------------------------------------------------------ 【ISR,タイムイベントハンドラ】 実行開始条件 解除 - 任意 任意 実行開始時処理 そのまま - そのまま そのまま リターン前 解除 - 元に戻す(*4) 変更不可 リターン時処理 未規定(*1) - 未規定(*1) そのまま ------------------------------------------------------------------------------ 【CPU例外ハンドラ】 実行開始条件 任意 - 任意 任意 実行開始時処理 そのまま - そのまま そのまま リターン前 元に戻す - 元に戻す(*4) 変更不可 リターン時処理 未規定(*1) - 未規定(*1) そのまま ------------------------------------------------------------------------------ 【拡張サービスコールルーチン】 実行開始条件 任意 - 任意 任意 実行開始時処理 そのまま - そのまま そのまま リターン前 任意 - 任意 任意 リターン時処理 そのまま - そのまま そのまま ------------------------------------------------------------------------------ (*1) リターン前の条件に従わずにリターンした場合の振舞いは未定義.リタ ーン前の条件に従えば,リターン直後はそのままとなる. (*2) 実装定義の方法に従わずリターンした場合の振舞いは未定義.実装定義 の方法に従えば,リターン直後はCPUロック解除状態となる. (*3)「任意」は次の理由で不都合である.dis_dspとena_dspの対をネストさせ たい場合の対処法として,μITRON4.0仕様では,sns_dspを用いる方法を提示し ている.ところが,非同期に実行されるタスク例外処理ルーチン中でディスパッ チ禁止/許可状態が変更されると,この方法では対応できない.また,これに 代わる良い方法も用意されていない.μITRON4.0仕様策定時の考慮不足と考え られる. (*4) 変更するためのAPIは標準では規定されていないため,「変更不可」と見 ることもできる. ○TOPPERS/ASPカーネルにおける実現(擬似コードベース) ●タスクの実行開始時処理 タスクの実行開始時は,CPUロック解除状態・割込み優先度マスク全解除状態・ ディスパッチ許可状態・タスク例外禁止状態としなければならない.以下,こ れが実現されていることを確認する. タスクの実行開始時は,ディスパッチャ本体(dispatcher)から,タスクを実 行開始する処理(start_r)に分岐し,そこからタスクの起動番地が呼び出され る. CPUロック解除状態については,start_rにおいて,CPUロック解除状態にする処 理が行われる. dispatcherは,タスクコンテキスト・CPUロック状態・割込み優先度マスク全解 除状態・ディスパッチ許可状態で呼び出され,同じ状態でstart_rへ分岐する. start_rでは,割込み優先度マスクとディスパッチ禁止フラグを変更しないため, タスクの実行開始時には,割込み優先度マスク全解除状態・ディスパッチ許可 状態となっている. ★dispatcherが上記条件で呼び出されることの確認が必要. タスク例外禁止状態については,make_dormantにおいて,TCBのenatexフィール ドをFALSEにしており,タスクが休止状態の間はこれが保たれる.そのため,タ スクの実行開始時には,特別な処理は必要ない. ●タスクの終了時処理 タスクの終了時には,CPUロック解除状態・割込み優先度マスク全解除状態・ディ スパッチ許可状態としなければならない.以下,これが実現されていることを 確認する. タスクの終了時にはext_tskが呼び出されるが,その中で,CPUロック状態で呼 ばれた場合にはその解除(コード上は,ext_tsk中でCPUロック状態に移行する 際に,CPUロック状態で呼ばれた場合には,移行処理を省略しているだけ),割 込み優先度マスク全解除以外で呼ばれた場合にはその全解除,ディスパッチ禁 止状態で呼ばれた場合にはディスパッチの許可を行っている. <未完成> ○TOPPERS/ASPカーネルにおける実現(M68040依存) ●タスクの実行開始 ディスパッチャ(dispatcher)は,タスクコンテキスト,CPUロック状態,ディ スパッチ許可状態,割込み優先度マスク全解除状態で呼び出される. M68040においては,★上の条件が満たされていることを確認する必要がある★. タスク実行開始時は,CPUロック解除状態,ディスパッチ許可状態,割込み優先 度マスク全解除状態としなければならないため,ディスパッチャからタスク実 行開始する処理(start_r)において,CPUロックを解除する. M68040においては,start_r中の次の処理でこれを実現している. ---------------------------------------- clr.l lock_flag /* CPUロック解除状態に */ and.w #~0x0700, %sr ---------------------------------------- start_rが実行される時には,(モデル上の)割込み優先度マスク全解除状態と なっているため,ステータスレジスタ(SR)中のIPMを0としてよい(saved_iipm に保存した値に戻す必要はない). make_dormantにおいて,TCBのenatexフィールドをfalseにしており,タスクが 休止状態の間はこれが保たれる.そのため,タスクの実行開始時にタスク例外 禁止状態とするために,特別な処理は必要ない. ●タスクの終了 ext_tskにおいて,CPUロック状態で呼ばれた場合にはその解除(コード上は, ext_tsk中でCPUロック状態に移行する際に,CPUロック状態で呼ばれた場合には, 移行処理を省略しているだけ),ディスパッチ禁止状態で呼ばれた場合にはディ スパッチの許可,割込み優先度マスク全解除以外で呼ばれた場合にはその全解 除を行っている. ●タスク例外処理ルーチンの実行開始 タスク例外処理ルーチンの呼出し処理(call_texrtn)は,タスクコンテキスト, CPUロック状態,タスク例外許可状態で呼び出される.ターゲット非依存部にお いては,ras_texとena_texからcall_texrtnを呼び出しているが,いずれもこの 条件を満たしている. M68040においては,dispatch_rとret_int_rの2箇所からcall_texrtnを呼び出し ている.dispatch_rが実行される時には,CPUロック状態となっており,タスク 例外許可状態の場合のみcall_texrtnを呼び出すようにしている.ret_int_rに ついても,実行される時にはCPUロック状態となっており,タスク例外許可状態 の場合のみcall_texrtnを呼び出すようにしている(call_texrtnを直接呼ぶ代 わりにcalltexを呼べば,calltexにおいて,タスク例外許可状態の場合のみ call_texrtnを呼び出すようになっている). タスク例外処理ルーチン実行開始時は,CPUロック解除状態,タスク例外禁止状 態としなければならないため,call_texrtnにおいてタスク例外処理ルーチンを 呼び出す前に,CPUロックを解除し,タスク例外禁止状態としている.また,ディ スパッチ禁止/許可状態と割込み優先度マスクは,呼び出し前の状態を保存す るのみで,状態の変更は行わない. ●タスク例外処理ルーチンからのリターン call_texrtnにおいてタスク例外処理ルーチンから戻った後に,CPUロック状態 への移行(CPUロック状態で戻ってきた場合には省略)と,ディスパッチ禁止/ 許可状態と割込み優先度マスクを呼び出し前の状態に戻す処理を行う.また, タスク例外許可状態とする(タスク例外処理ルーチンを続けて呼び出す場合に は,タスク例外許可状態にはしない).CPUロック状態の解除は,call_texrtn からリターンした後に行う. ターゲット非依存部において,ras_texとena_texからcall_texrtnが呼び出され た場合には,call_texrtnからのリターンによりサービスコール処理関数に戻る. サービスコール処理関数では,call_texrtnから戻った後に,t_unlock_cpuを呼 び出してCPUロック状態を解除する. M68040において,dispatch_rからcall_texrtnが呼び出された場合には, call_texrtnからのリターンにより,直接サービスコール処理関数に戻る (dispatchの呼出しから戻る).サービスコール処理関数では,dispatchから 戻った後に,t_unlock_cpuを呼び出してCPUロック状態を解除する. ret_int_rからcall_texrtnが呼び出された場合には,call_texrtnからのリター ン後に,lock_flagをクリアし,rte命令によりIPMを割込み発生前の値に戻して, CPUロック状態を解除する.このケースはさらに,ret_intにおいてタスク切換 えを行った場合と,行わなかった場合(タスク例外処理ルーチンを実行するた めにreqflgをセットした場合)に分類できるが,いずれの場合も,rte命令によ り,IPMはタスクが割込みを受け付けた時の状態に戻り,仕様に合致した振舞い となっている. ●割込みハンドラの実行開始 割込みハンドラの実行開始時には,ターゲット依存部において,割込み優先度 マスクを,実行開始する割込みハンドラの割込み優先度に設定する. M68040においては,割込み優先度マスクの変更は,ハードウェアで行われるた め,ソフトウェアでは特別の処理を行う必要がない. ●割込みハンドラからのリターン 割込みハンドラからのリターン時には,ターゲット依存部において,CPUロック 解除状態に戻し,割込み優先度マスクを割込みハンドラ実行開始前の値に戻す. M68040においては,割込みハンドラからの出口処理(ret_int)の処理を,いく つかの実行経路に分けて確認する必要がある. (1) 戻り先が非タスクコンテキストか,reqflgがfalseの場合には,ret_int_1 において,lock_flagをクリアし,rte命令によりIPMを割込み発生前の値に戻し て,CPUロック状態を解除し,割込み優先度マスクを元の値に戻す. (2) タスク切換えが必要な場合には,CPUロック状態に移行して,ディスパッチャ (dispatcher)へ分岐する.この際に,割込み発生前のIPM(ディスパッチ保留 状態でないことから,TIPM_ENAALLになっているはず)を,saved_iipmに保存す る.これにより,次に実行すべきタスクへと戻る前にCPUロック状態を解除する タイミングで,CPUロック状態を解除し,割込み優先度マスクが割込み発生前の 値に設定されることになる. (3) タスク切換えが必要なく,タスク例外処理ルーチンの実行が必要な場合に は,CPUロック状態に移行して,call_rettexを呼び出す.この際に,割込み発 生前のIPM(TIPM_ENAALLであるとは限らない)を,saved_iipmに保存する.こ れにより,call_rettexの中でタスク例外処理ルーチンを呼び出す前にCPUロッ ク状態を解除するタイミングで,CPUロック状態を解除し,割込み優先度マスク が割込み発生前の値に設定されることになる. ●割込みサービスルーチン(ISR)の実行開始 割込みサービスルーチン(ISR)は,コンフィギュレータが生成する割込みハン ドラから呼び出す.ISRの呼出しは,割込みハンドラの実行開始後にそのままの 状態で行うか,他のISRからリターンした後に元の状態に戻した後に行う.いず れの場合も,ISRの実行開始時の条件を満たしている. ●割込みサービスルーチン(ISR)からのリターン 割込みサービスルーチン(ISR)からのリターン後の処理は,コンフィギュレー タが生成する割込みハンドラに含まれる.そこでは,CPUロック状態であればそ れを解除し,割込み優先度マスクをISR呼出し前の値に戻す. ●タイムイベントハンドラの実行開始 周期ハンドラはターゲット非依存部のcall_cychdrから,アラームハンドラはター ゲット非依存部のcall_almhdrから呼び出す.いずれも,呼出し前にCPUロック 状態を解除する.ここで,CPUロック状態に移行したのはsignal_timeの中のは ずなので,割込み優先度マスクは,signal_timeが呼ばれた時の値に設定される. ●タイムイベントハンドラからのリターン タイムイベントハンドラからのリターン後の処理は,周期ハンドラについては ターゲット非依存部のcall_cychdrに,アラームハンドラについてはターゲット 非依存部のcall_almhdrに含まれる.そこでは,CPUロック状態でなければCPUロッ ク状態に戻し(CPUロック状態の解除は,signal_timeで行われる),割込み優 先度マスクをタイムイベントハンドラ呼出し前の値に戻す. ●CPU例外ハンドラの実行開始 CPU例外ハンドラの実行開始時には,実行開始前のシステム状態を保存するのみ で,システム状態をそのまま引き継ぐ. M68040においては,例外処理実行開始直後のステータスレジスタ(SR)と lock_flagをスタックに保存した後,システム状態を変更せずに,CPU例外処理 ルーチンを呼び出す. ●CPU例外ハンドラからのリターン CPU例外ハンドラからのリターン時には,ターゲット依存部において,CPUロッ ク/ロック解除状態と割込み優先度マスクを,CPU例外ハンドラ実行開始前の状 態に戻す. M68040においては,CPU例外ハンドラからの出口処理(ret_exc)において,ま ず,lock_flagを元の値に戻している.割込み優先度マスクについては,いくつ かの実行経路に分けて確認する必要がある. (1) 戻り先が非タスクコンテキストか,reqflgがfalseの場合には,ret_exc_2 において,rte命令によりIPMを割込み発生前の値に戻して,割込み優先度マス クを元の値に戻す.CPUロック状態でCPU例外が発生した場合には,reqflgが trueになることはないので,この経路で実行される. (2,3) その他の場合は,CPUロック解除状態でCPU例外が発生した場合であり, 割込みハンドラからの出口処理と同様である. 以上