TOPPERS/ASP3カーネル GIC(ARM Generic Interrupt Controller)依存部 設計メモ 対応バージョン: Release 3.B.0 最終更新: 2015年7月24日 ---------------------------------------------------------------------- ○目次 ・参考文献 ・GIC依存部の位置づけ - GIC依存部を構成するファイル ・チップ依存のパラメータ ・GICにおける割込みハンドラおよびCPU例外ハンドラの出入口処理 - GICにおける割込みハンドラの出入口処理 ○参考文献 [1] TOPPERSプロジェクト 設計メモ「GIC(ARM Generic Interrupt Controller)に関するメモ」. ○GIC依存部の位置づけ GIC依存部は,カーネルのターゲット依存部の中で,GICアーキテクチャ (GICv1およびGICv2)に準拠した割込みコントローラを持つチップに共通に使 用できる部分である.また,GICの前身と思われるARM11 MPCoreのDistributed Interrupt Controllerにも適用できるように実装する. TOPPERS_SAFEG_SECUREがマクロ定義されている場合には,GICがセキュリティ拡 張されていることを想定し,セキュアモードで使用するものとする. GICv1とGICv2でレジスタ名が変更になっているが,ソースコード中では, GICv2のレジスタ名を使用する. ●GIC依存部を構成するファイル GIC依存部は,次の3つのファイルで構成される. gic_kernel_impl.h gic_kernel_impl.c gic_support.S ○チップ依存のパラメータ TMIN_INTPRI TMAX_INTPRI カーネルのターゲット依存部のヘッダファイルからgic_kernel_impl.hをインク ルードする前に,必要に応じて,以下の定数をマクロ定義しておく. (1) GIC_TNUM_INTNO 割込みの数 ターゲットチップのGICがサポートする割込みの数.SGI(Software Generated Interrupt),PPI(Private Peripheral Interrupt),SPI(Shared Peripheral Interrupt)の合計数. (2) GIC_PRI_LEVEL 割込み優先度の段数 ターゲットチップのGICがサポートする割込み優先度の段数.16,32,64,128, 256のいずれか. (3) GICC_BASE CPUインタフェースのベースアドレス (4) GICD_BASE ディストリビュータのベースアドレス GICのCPUインタフェースおよびディストリビュータのベースアドレス. (5) TOPPERS_SAFEG_SECURE セキュアモード(オプション) セキュアモードでカーネルを動作させ,FIQをカーネル管理の割込みと扱う場合 に,このシンボルをマクロ定義する. (6) GIC_ARM11MOCORE ARM11 MPCoreへの対応(オプション) ARM11 MPCoreのDistributed Interrupt Controllerの場合には,このシンボル をマクロ定義する. ○GICにおける割込みハンドラおよびCPU例外ハンドラの出入口処理 ●GICにおける割込みハンドラの出入口処理 GICにおける割込みハンドラの出入口処理(irc_begin_intおよびirc_end_int) の実現方法には,いくつかのアプローチがある. 【アプローチ1】 このアプローチは,GICの想定している(よって,最もシンプルな)ものである. 割込みハンドラの入口では何も行わず,割込みハンドラの出口でEOIを発行する. ---------------------------------------- ALABEL(irc_begin_int) /* * 割込み要因を取得する. */ ldr r1, =GICC_IAR ldr r3, [r1] push {r3} /* irc_end_intで用いる情報を保存 */ /* * 割込み番号を返値としてリターンする. */ lsl r0, r3, #22 /* 下位10ビットを取り出す */ lsr r0, r0, #22 bx lr ALABEL(irc_end_int) /* * EOIを発行してリターンする. */ pop {r3} /* irc_begin_intで保存した情報を復帰 */ ldr r1, =GICC_EOIR /* EOIレジスタへの書込み */ str r3, [r1] bx lr ---------------------------------------- このアプローチには,次の問題点がある. (1) 割込みハンドラからのリターン時に,割込み優先度マスクを元に戻すとい う仕様を実装していると言えるか微妙である.特に,CPU例外ハンドラをこれと 整合するように実装した場合,割込み優先度マスクを一切操作しないという実 装になり,仕様に準拠していないように思われる. (2) 割込み優先度が256段階ある時(この場合,ARM GICでは,割込み優先度の すべてのビットをプリエンプションに使うという設定ができない)に,このア プローチでは,割込み優先度のすべてのビットをプリエンプションに使うこと ができず,TOPPERS標準割込み処理モデルからの逸脱となる. (3) 割込みハンドラから割込み優先度マスクを参照/設定することができない. ASP3カーネルでは問題ないが,ATK2カーネルでは,このアプローチは用いるこ とができない. 【アプローチ2】 問題点(1)と(3)を解決するためには,発生した割込み要因の割込み優先度を, 割込み優先度マスクに設定しておく方法が考えられる. ---------------------------------------- ALABEL(irc_begin_int) /* * 割込み要因を取得する. */ ldr r1, =GICC_IAR ldr r3, [r1] /* * 割込み要因の割込み優先度を求め,割込み優先度マスクに設定する. */ ldr r1, =GICC_RPR /* 受け付けた割込みの割込み優先度を取得 */ ldr r0, [r1] ldr r1, =GICC_PMR /* 割込み発生前の割込み優先度を取得 */ ldr r2, [r1] str r0, [r1] /* 新しい割込み優先度マスクをセットする */ DATA_SYNC_BARRIER /* 割込み優先度マスクがセットされるのを待つ */ push {r2,r3} /* irc_end_intで用いる情報を保存 */ /* * 割込み番号を返値としてリターンする. */ lsl r0, r3, #22 /* 下位10ビットを取り出す */ lsr r0, r0, #22 bx lr ALABEL(irc_end_int) /* * EOIを発行する. */ pop {r2,r3} /* irc_begin_intで保存した情報を復帰 */ ldr r1, =GICC_EOIR /* EOIレジスタへの書込み */ str r3, [r1] /* * 割込み優先度マスクを元に戻してリターンする. */ ldr r1, =GICC_PMR str r2, [r1] bx lr ---------------------------------------- しかし,このアプローチでは,アプローチ1の2つめの欠点は解決できない. 【アプローチ3】 アプローチ1の2つめの欠点を解決するためには,割込みハンドラの入口処理で EOIを発行してしまう方法が考えられる. ---------------------------------------- ALABEL(irc_begin_int) /* * 割込み要因を取得する. */ ldr r1, =GICC_IAR ldr r3, [r1] /* * 割込み要因の割込み優先度を求め,割込み優先度マスクに設定する. */ ldr r1, =GICC_RPR /* 受け付けた割込みの割込み優先度を取得 */ ldr r0, [r1] ldr r1, =GICC_PMR /* 割込み発生前の割込み優先度を取得 */ ldr r2, [r1] str r0, [r1] /* 新しい割込み優先度マスクをセットする */ DATA_SYNC_BARRIER /* 割込み優先度マスクがセットされるのを待つ */ push {r2} /* irc_end_intで用いる情報を保存 */ /* * EOIを発行する. */ ldr r1, =GICC_EOIR /* EOIレジスタへの書込み */ str r3, [r1] /* * 割込み番号を返値としてリターンする. */ lsl r0, r3, #22 /* 下位10ビットを取り出す */ lsr r0, r0, #22 bx lr ALABEL(irc_end_int) /* * 割込み優先度マスクを元に戻してリターンする. */ pop {r2} /* irc_begin_intで保存した情報を復帰 */ ldr r1, =GICC_PMR /* 割込み優先度マスクを元に戻す */ str r2, [r1] bx lr ---------------------------------------- 現在の実装では,アプローチ3を採用している. ●GICにおけるCPU例外ハンドラの出入口処理 以上