プロセッサに依存するカーネル用の設定を行うためのファイルです。
SUPPORT_CHG_IPMはchg_ipm()関数を実装するときに定義する条件コンパイル用マクロシンボルです。chg_ipm()関数は割り込み許可順位を設定するための関数ですがm68Kのアーキテクチャーに傾いており、Blackfinのそれとはあまり合わないために実装しないことにします。
今回の実装ではSUPPORT_CHG_IPMは定義しません。
これはm68Kの実装で使われている値をそのまま使用します。
タスク切り替えのときに対比すべきリソース用の領域を確保します。
typedef struct task_context_block { VP sp; /* スタックポインタ */ FP pc; /* プログラムカウンタ */ } CTXB;
現在のコンテキスト状態を返します。
IVG15がタスクコンテキストなのでそれ以外の状態にあれば非タスクコンテキストであると認識できます。これに使えるのはIPENDレジスタで、ネスティングされているすべての割り込みをビットマップとして表します。
bit15がIVG15に相当しますのでそれ以外のビットが1であれば非タスクコンテキストとなります。
Inline BOOL sense_context() { return(*pIPEND != 0x8000); }
現在のCPUロック状態を返します。
ロック状態はIMASKレジスタで制御します。ロック状態ではIMASKはIVG15に相当するbit15とカーネルでの割り込み待ちに使うIVG14に相当するbit14のみを許可します。厳密にはIVG15は許可しなくてもいいのですが、精神衛生上の理由で1にします。ロック状態でもbit4-0はハードウェアによって1にされています。
これらをまとめて0xC01FがIMASKに設定されていればロック状態と判定します。
Inline BOOL sense_lock() { return(*pIMASK == 0xC01F); }
CPUを割り込み禁止にします。タスクコンテキストから呼ばれる関数です。割り込み禁止はIMASKへ0XC000を書き込むことで実装します。IVG14を許可しているのはこの割り込みレベルがタスクディスパッチャ内部での割り込み待ち状態に置くときに使われるため、禁止してはならないからです。IVG15はタスクコンテキストのレベルです。わざわざ許可する必要はありませんが、精神衛生上の理由で許可しておきます。
sti(), csync()はそれぞれBlackfinの sti, csync命令を実行します。csync命令はパイプライン中にある全ての命令がコア内部で実行を終了するのを待ちます。この場合はstiによるロックが完了してから次に進みます。
Inline void t_lock_cpu() { sti(0xC000); csync(); }
CPUを割り込み可能にします。タスクコンテキストから呼ばれます。割り込み許可はIMASKへ0xFFFFを書き込みます。csync();がstiの前にありますので、保護区間の命令実行が完了してからアンロックが行われます。
Inline void t_unlock_cpu() { csync(); sti(0xFFFF); }
CPUをロック、アンロックする関数で、非タスクコンテキストから呼ばれます。Blackfin実装ではタスクコンテキストのロック・アンロックと同じです。
カーネルが任意の割り込み順位にハンドラのアドレスを設定するための関数を定義します。evtvectorはstart.asmの中で定義されているポインタ配列です。ここにはC言語の関数を登録します。登録された関数は割り込みハンドラとしてプロセッサ依存の割り込みディスパッチャから呼び出されます。
m68k実装ではこの部分が直接プロセッサの割り込みベクトルをアクセスします。また、渡されるのはタスク例外とタスクディスパッチのラッパーを付加された割り込みハンドラです。Blackfin実装ではこれらのラッパーを付加しません。替わりに、タスク例外とタスクディスパッチ部分はプロセッサ依存の割り込みディスパッチャが保持します。
extern void *evtvector[]; Inline void define_inh(INHNO inhno, FP inthdr) { evtvector[inhno] = inthdr; }