TOPPERSプロジェクト 設計メモ GIC(ARM Generic Interrupt Controller)に関するメモ 作成者: 高田広章(名古屋大学) 最終更新: 2015年7月25日 ○メモの位置づけ このメモは,ARM Generic Interrupt Controller(GIC)に関して,TOPPERSカー ネルをポーティングするにあたって必要となる事項をまとめたものである. ○目次 ・参考文献 ・GICのアーキテクチャ仕様 ・PrimeCell GIC(Generic Interrupt Controller)PL390 ・ARM11 MPCore Distributed Interrupt Controller ○参考文献 [1] ARM Generic Interrupt Controller - Architecture version 2.0 Architecture Specification, 2013 IHI0048B_b_gic_architecture_specification.pdf [2] PrimeCell Generic Interrupt Controller (PL390) Technical Reference Manual Revision: r0p0 DDI0416B_gic_pl390_r0p0_trm.pdf [3] ARM11 MPCoreTM Processor Technical Reference Manual Revision: r2p0 DDI0360F_arm11_mpcore_r2p0_trm.pdf ○GICのアーキテクチャ仕様([1]) GICのアーキテクチャにも,GICv1とGICv2の2つのバージョンがある.バージョ ンによりレジスタ名も異なる.ここでは,GICv2のアーキテクチャについて記述 する.仮想化拡張については記述を省略する. ●用語の定義 割込み状態 - Inactive:ActiveでもPendingでもない状態 - Pending:要求は認識されており,サービスを待っている状態 - Active:プロセッサによって受け付けられ,サービスされている状態 - Active and pending:プロセッサがサービスしているが,同じ割込み源 からの要求がさらにある場合 割込みのタイプ - ペリフェラル割込み(Peripheral Interrupt) + プライベートペリフェラル割込み(PPI, Private Peripheral Interrupt) *特定のプロセッサ向けの割込み + 共有ペリフェラル割込み(SPI, Shared Peripheral Interrupt) *プロセッサを限定しない割込み - ソフトウェアで生成する割込み(SGI, Software Generated Interrupt) - 仮想割込み(Virtual Interrupt)… 仮想化拡張のみ - メンテナンス割込み(Maintenance Interrupt)… 仮想化拡張のみ 割込みハンドリングのモデル … マルチプロセッサの場合 - 1-Nモデル:ターゲットプロセッサの内の1つのみが割込みを処理する - N-Nモデル:すべてのターゲットプロセッサが割込みを処理する *GICは,SGIはN-Nモデル,ペリフェラル割込みは1-Nモデルで扱う ●割込みグループ 2つの割込みグループ(セキュアモード用のグループ0,ノンセキュアモード用 のグループ1)をサポート.GICv1では,セキュリティ拡張がある時のみ,割込 みグループをサポート. ・各割込みをグループ0またはグループ1に設定可能 ・グループ0は,ターゲットプロセッサに,IRQまたはFIQで通知 ・グループ1は,ターゲットプロセッサに,IRQで通知 ・両グループの割込みの優先度を統一して扱える ・グループ0の割込みの設定をロックダウンするオプションあり 注意)優先度グループは,割込みグループとは別の概念なので,混同しないこと!    優先度グループは,セキュリティ拡張とは無関係の機能 ●ディストリビュータ ディストリビュータの機能(ソフトウェアから見えるもの) - 割込み要求をCPUインタフェースに送る - 各割込みの禁止/許可 - 各割込みの優先度レベルの設定 - 各割込みのターゲットプロセッサリストの設定 - 各ペリフェラル割込みのレベルトリガ/エッジトリガの設定 ※レベルトリガは,level-sensitiveと書かれている - 各割込みのグループ0/グループ1の設定 - SGIを1つまたは複数のターゲットプロセッサに送る - 各割込みの状態の参照 - ペリフェラル割込みのペンディング状態のソフトウェアからの操作 割込みID - 最大で1020の割込みID.バンクを使うとさらに多くの割込みを扱える - 割込みIDの構成 0〜15:SGI … CPUインタフェース毎 0〜7:ノンセキュア用に使うことを強く推奨 8〜15:セキュア用に使うことを強く推奨 16〜31:PPI … CPUインタフェース毎 32〜1019:SPI 1020〜1023:特殊目的に予約 1020〜1021:予約 1022:割込みグループに伴うスプリアス割込み(詳細省略) 1023:スプリアス割込み ●CPUインタフェース CPUインタフェースの機能(ソフトウェアから見えるもの) - プロセッサへの割込み要求信号の許可 - 割込みの受付け(acknowledging) - 割込み処理完了の通知 - 割込み優先度マスクの設定 - プリエンプションポリシーの設定 - ペンディングしている最高優先度割込みの取得 割込みの受付け - プロセッサが割込みアクノーレッジレジスタ(IAR)を読むことで,割込 みが受け付けられる - IARからは,割込みIDが返る(スプリアス割込みのIDである場合も) - 割込み状態は,pendingからactive(またはactive and pending)に遷移 割込みの完了 - プロセッサが割込み完了レジスタ(GICC_EOIR)に書くことで,割込の完 了が通知される - GICは次の2つの処理を実行する + 優先度マスクを下げる + 割込みをdeactivateする(activeから他の状態に遷移させる) - GICv2では,設定により,GICC_EOIRへの書き込みでは1つめのステップの み行い,別のレジスタ(GICC_DIR)への書き込みで2つめのステップを実 行させることができる 割込み信号バイパスとバイパス禁止 <詳細省略> - レガシー割込みを扱うために,割込み要求をバイパスする機能がある - GICv2では,バイパスを禁止する機能がある ●割込みのハンドリング(セキュリティ拡張がない場合) ・割込みハンドリング状態マシンで,4つの割込み状態の間の遷移を定義 ・GICの割込みハンドリングシーケンス 1. 割込みがイネーブルされているかどうかを判定 2. ペンディングしている割込みに対して,ターゲットプロセッサを決定 3. ディストリビュータは,各プロセッサに対して,ペンディングしている 最高優先度割込みを決定し,CPUインタフェースに送る 4. CPUインタフェースは,ディストリビュータから送られてきた割込みが 十分に高い優先度か決定し,十分に高ければ,プロセッサに送る 5. プロセッサが割込みを受け付けると,GICは割込みIDを返し,割込み状態 を更新する 6. 割込みの処理が終わると,プロセッサは割込み完了をGICに通知する ●割込みの優先度付け(割込みグループとセキュリティ拡張がない場合) ・GICがサポートする割込み優先度の数は,16〜256 ・割込み優先度は,8ビットの符号無し整数で表す 値が小さい方が優先度が高い 優先度の数が256より少ないときは,上位ビットから使用する 使わない下位ビットはRAZ/WI ・各割込みの優先度を個別に設定できる 実装によって,特定の割込みの優先度を固定してもよい ・同じ優先度の割込みの中でどれを受け付けるかは実装依存 ・割込みのプリエンプションは次の2つの条件が揃った時に起こる - 割込みの優先度が,割込み優先度マスクよりも高い - 割込みのグループ優先度が,実行中優先度のグループ優先度よりも高い ・割込み優先度マスク(GICC_PMR) - CPUインタフェースのGICC_PMRよりも高い割込みのみを受け付ける + この判定に,優先度のグループは影響しない - 割込みに最低優先度(値としては最大)を割り付けると,その割込みは 受け付けられない ・優先度グルーピング - バイナリポイントレジスタ(GICC_BPR)の設定により,割込み優先度を, グループ優先度とサブ優先度に分けることができる - プリエンプションにおいては,同じグループの優先度は,同じ優先度と 見なされる(つまり,同じグループ内ではプリエンプションは起きない)  !割込み優先度が8ビットの時は,すべてでプリエンプションを起こす設定は できない ●割込みグループと割込みのハンドリング(セキュリティ拡張) ●割込みグループと割込みの優先度付け(セキュリティ拡張) ・次のことを強く推奨する - グループ0には,半分より高い優先度(最上位ビットが0)を割り当てる - グループ1には,半分より低い優先度(最上位ビットが1)を割り当てる ・ノンセキュアモードから見える割込み優先度 - ノンセキュアモードからは,グループ1の割込みのみが扱える - 書き込み時には,1ビット右にシフトされ,最上位ビットが1になる - 読み出し時には,1ビット左にシフトされる(最上位ビットはなくなる) ・各グループの割込みのプリエンプションの制御 - GICC_BPRには,セキュアコピーとノンセキュアコピーがある + セキュアモードからアクセスすると,セキュアコピーにアクセス + ノンセキュアモードからアクセスすると,ノンセキュアコピーにアクセス - グループ0は,GICC_BPRのセキュアコピーで制御される - グループ1は, GICC_CTLR.CBPRが0の時,GICC_BPRのノンセキュアコピーで制御される GICC_CTLR.CBPRが1の時,GICC_BPRのセキュアコピーで制御される - GICC_ABPRは,セキュアモードから,GICC_BPRのノンセキュアコピーにア クセスするためのレジスタ ・GICC_BPRのノンセキュアコピーの設定 - GICC_CTLR.CBPRが0の時,グループ1のプリエンプションには,GICC_BPRの ノンセキュアコピーから「1引いた値」が使われる - GICC_BPRのノンセキュアコピーに,0は設定できない ●プログラミングモデル(Programmers' Model) レジスタ名のコンベンション GICD_xxxx … ディストリビュータのレジスタ GICC_xxxx … CPUインタフェースのレジスタ GICH_xxxx … 仮想インタフェース制御レジスタ(ハイパバイザが使う) GICV_xxxx … 仮想CPUインタフェースのレジスタ レジスタに関する原則 ・すべてのレジスタは32ビット幅 ・予約はすべてRAZ/WI ●ディストリビュータのプログラミングモデル ディストリビュータ制御レジスタ(GICD_CTLR)0x000 [31:2] 予約 [1] EnableGrp1 … セキュリティ拡張の場合のみ 0:グループ1の割込みをフォワードしない 1:グループ1の割込みをフォワードする [0] Enable … セキュリティ拡張なし/EnableGrp0 … セキュリティ拡張 0:(グループ0の)割込みをフォワードしない 1:(グループ0の)割込みをフォワードする 割込みコントローラタイプレジスタ(GICD_TYPER)0x004,RO ディストリビュータ実装IDレジスタ(GICD_IIDR)0x008,RO 割込みグループレジスタ(GICD_IGROUPRn)0x080 … セキュリティ拡張 割込みイネーブルセットレジスタ(GICD_ISENABLERn)0x100〜0x17c 割込みイネーブルクリアレジスタ(GICD_ICENABLERn)0x180〜0x1fc - 各割込みをイネーブルするかどうかを制御するレジスタ - セットレジスタの対応するビットに1を書くとイネーブル - クリアレジスタの対応するビットに1を書くとディスエーブル - どちらのレジスタを読んでも,イネーブルされている割込みに対して1が返る 割込みペンディングセットレジスタ(GICD_ISPENDRn)0x200〜0x27c 割込みペンディングクリアレジスタ(GICD_ICPENDRn)0x280〜0x2fc - 各割込みがペンディング状態かどうかを制御するレジスタ - SGIは,このレジスタでセット/クリアできない(別のレジスタを使う) - セットレジスタの対応するビットに1を書くとペンディング状態に + アクティブ状態の場合は,"active and pending"に - クリアレジスタの対応するビットに1を書くとペンディング状態を解除 + "active and pending"の場合は,アクティブ状態に - レベルトリガの場合でも,このレジスタで要求した割込みはエッジトリガの ように振る舞う(このレジスタで要求した割込みを記憶するFFがある) - どちらのレジスタを読んでも,ペンディングされている割込みに対して1が返る マルチプロセッサのSGIとPPIに関しては,自プロセッサに対して ペンディングされているかどうかが返る 割込みアクティブセットレジスタ(GICD_ISACTIVERn)0x300〜0x37c … GICv1では割込みアクティブビットレジスタでRO 割込みアクティブクリアレジスタ(GICD_ICACTIVERn)0x380〜0x3fc 割込み優先度レジスタ(GICD_IPRIORITYRn)0x400〜0x7f8 - 各割込みの優先度を8ビットで設定 *バイト単位でアクセス可能 割込みターゲットレジスタ(GICD_ITARGETSRn)0x800〜0xbf8 … マルチコアのみ … 最初の32個(ターゲット固定)はRO - 各割込みのターゲットプロセッサのリストを8ビットのビットマップで設定 *バイト単位でアクセス可能 割込みコンフィギュレーションレジスタ(GICD_ICFGRn)0xc00〜0xcfc - 各割込みのコンフィギュレーションを2ビットで設定 - レベルトリガかエッジトリガかを設定 - GICv1より前の一部の実装では,N-Nモデルか1-Nモデルかもここで設定 0:N-Nモデル 1:1-Nモデル 割込みノンセキュアアクセス制御レジスタ(GICD_NSCARn)0xe00〜0xefc … オプション SGIレジスタ(GICD_SGIR)0xf00,WO - SGIを発生させるレジスタ SGIペンディングクリアレジスタ(GICD_CPENDSGIRn)0xf10〜0xf1c SGIペンディングセットレジスタ(GICD_SPENDSGIRn)0xf20〜0xf2c - SIGがペンディング状態かどうかを制御するレジスタ 他に,実装定義レジスタがある ●CPUインタフェースのプログラミングモデル CPUインタフェース制御レジスタ(GICC_CTLR)0x000 割込み優先度マスクレジスタ(GICC_PMR)0x004 バイナリポイントレジスタ(GICC_BPR)0x008 - 割込み優先度を,グループ優先度とサブ優先度に分ける位置を設定 [31:3] 予約 [2:0] 分割位置(gがグループ優先度,sがサブ優先度) 0:上位7ビットがグループ優先度 ggggggg.s 1:上位6ビットがグループ優先度 gggggg.ss 6:再上位ビットがグループ優先度 g.sssssss 7:プリエンプションしない ssssssss !優先度が8ビットの時は,全ビットをグループ優先度にすることはできない 割込みアクノーレッジレジスタ(GICC_IAR)0x00c,RO 割込み完了レジスタ(GICC_EOIR)0x010,WO 実行中優先度レジスタ(GICC_RPR)0x014,RO 最高優先度ペンディング割込みレジスタ(GICC_HPPIR)0x018,RO <省略:セキュリティ拡張のためのレジスタ> CPUインタフェースIDレジスタ(GICC_IIDR)0x00fc,RO 割込みディアクティベートレジスタ(GICC_DIR)0x1000,WO … GICv2のみ ○PrimeCell GIC(Generic Interrupt Controller)PL390([2]) このGICは,「ARM Generic Interrupt Controller Architecture」(明記して いないが,GICv1と思われる)に準拠 ここで言う「コンフィギュレーション」とは,ハードウェアIPのコンフィギュ レーションのこと ●GICの構成 - ディストリビュータ … 1つだけ + 外部からの割込みを受け取り,最高優先度のものをCPUインタフェースに送る - CPUインタフェース … プロセッサ毎に - その他のブロック + AMBAスレーブインタフェース + クロックとリセット + enableとmatch信号 *制御レジスタを操作できるプロセッサを限定する機能 ●GICの機能 ・3タイプの割込み(SIG,PPI,SPI)をサポート ※その他にレガシー割込み(legacy interrupt)がある ・割込みを次のようにプログラム可能 - セキュリティ状態 - 割込みレベル - 割込みの禁止/許可 - 割込みを受け取るプロセッサ ・セキュリティ拡張に対応可能 ●コンフィギュレーションオプション <関係しそうな項目のみ> - セキュリティ拡張のサポートの有無 - CPUインタフェースの数 - ロック可能なSPI(要調査)の数 - PPI関連 + CPUインタフェース毎の数(0〜16) + レベルトリガかエッジトリガか + 素通しか登録か同期か - プロセッサ毎のSGIの数(0〜16) - SPI関連 + 数(1〜988) + 素通しか登録か同期か - レガシー割込み関連 + サポートの有無(0〜2) + レベルトリガかエッジトリガか + 素通しか登録か同期か - 優先度レベルの数 - The number of register slices in the highest pending interrupt logic. ●割込み受付(ディストリビュータの機能) - 割込みの登録(registering)と同期(synchronizing) + 素通し・登録・同期の3つから1つを,コンフィギュレーションで決める + 登録 … 割込み要求を次のクロックで受け取る + 同期 … 割込み要求を次の次のクロックで受け取る - エッジ検出 + レベルトリガ,エッジトリガの2つから1つを選べる + PPIは,コンフィギュレーション時に決める ●CPUインタフェース - 次の両方よりも優先度が高い割込みを受け付ける + プログラムできる割込み優先度マスク + プロセッサがサービス中の割込み ●実装定義事項 <関係しそうな項目のみ> 「ARM Generic Interrupt Controller Architecture」で実装定義とされている 事項を,このGICでは次のように定義している. - PPIのトリガモードは,コンフィギュレーション時に決定し,レジスタの 設定で変えられない - アクティブまたはアクティブペンディングの割込みの優先度レベルを変更 した場合の振舞い:このGICは新しい優先度レベルをすぐに使う - 同じ優先度の割込み間の優先関係:略 - ターゲットプロセッサが複数のSPIの調停:このGICは調停をしない.す べてのターゲットプロセッサに同時に割込み要求を送り,最初に応答し た(IARを読んだプロセッサ)が割込みIDを受け取る.他のプロセッサに は,スプリアス割込みが返る. ○ARM11 MPCore Distributed Interrupt Controller([3]の第10章) ※ARM11 MPCoreのDistributed Interrupt Controllerは,GICの前身と思われる. マニュアル中にGICという用語は出てこないが,GICとほぼ互換で使用できる. Distributed Interrupt Controllerは,次の2つで構成される. - 割込みディストリビュータ - CPU割込みインタフェース ●割込みディストリビュータ ・割込み要求をプロセッサに分配するユニット.割込み毎に,優先度と,ター ゲットプロセッサのリストを設定できる. ・割込み源には,以下のものがある. - プロセッサ間割込み(IPI)… GICのSGIに相当 + ソフトウェアから要求する割込み.ID0〜ID15 - プライベートタイマとウォッチドッグ … GICのPPIに相当 + ARM11 MPCore内蔵タイマからの割込み.ID29とID30 - レガシーなnIRQピン … GICの割込みバイパスに相当 + 各プロセッサに直結.ID31 - ハードウェア割込み … GICのSPIに相当 + 各割込み要求ラインに対応する割込み.ID32〜最大ID255 ・nFIQは扱えない.nFIQの要求ラインは,各プロセッサに直結される. ・割込みディストリビュータは,プロセッサ毎にペンディングしている割込み  のリストを持ち,その中で最も優先度の高いものを選んで,CPU割込みインタ  フェースに通知する. - 優先度が同じ割込みの間では,IDが小さい方が優先 - 1-NモデルとN-Nモデルの両方をサポート + 1-Nモデルで,複数のプロセッサが同時にIARにアクセスすると,同 じ割込みが通知される !割込み処理のソフトウェアで解決しなければならない! ※複数のターゲットプロセッサへの通知は使わない方が無難 ●割込みディストリビュータのレジスタ ・割込みコンフィギュレーションレジスタで,1-NモデルかN-Nモデルかを設定する 「GICv1より前の一部の実装」に該当 ●CPU割込みインタフェースのレジスタ ・レジスタの一覧 レジスタ名 オフセット --------------------------------------------------- Control Register 0x00 R/W Priority Mask Register 0x04 R/W Binary Pointer Register 0x08 R/W Interrupt Acknowledge Register 0x0c RO End of Interrupt Register 0x10 WO Running Priority Register 0x14 RO Highest Pending Interrupt Register 0x18 RO ・制御レジスタ [31:1] 予約 [1] Enable 0:外部nIRQ入力のみが有効 1:すべての割込み入力が有効 ・優先度マスクレジスタ [31:8] SBZ [7:4] 優先度マスク 0x0:すべての割込みをマスク ... 0xE:割込み優先度14〜15をマスク 0xF:割込み優先度15のみマスク ※割込み優先度15は受け付けられない [3:0] SBZ ※カーネルの割込み優先度マスクとの対応 0x0 -15 ... 0xE -1 0xF 0 ・バイナリポイントレジスタ [31:3] 予約 [2:0] Binary point 割込み優先度のどのビットをプリエンプションの 判断に使うか? 0x3:すべてのビットを使う(デフォルト) 0x4:上位3ビットを使う 0x5:上位2ビットを使う 0x6:最上位ビットのみ使う 0x7:プリエンプションしない 他の値を書くと,0x03を書いたのと同じになる ・割込みアクノーレッジレジスタ [31:13] SBZ/RAZ [12:10] ソースCPU ID プロセッサ間割込みを要求したプロセッサID [9:0] 割込みID 1023:スプリアス割込み ・割込み完了レジスタ 割込み処理の完了を通知するためのレジスタ 割込みアクノーレッジレジスタと同じフォーマット ・実行中優先度レジスタ 最後にアクノーレッジして,まだ完了していない割込みの優先度 [31:8] 予約 [7:4] 優先度 [3:0] SBZ ・最高優先度ペンディング割込みレジスタ ペンディングしている割込みの中で最高優先度のものを取得するためのレジスタ ペンディングしている割込みがない時は,割込みIDとして1023を返す 割込みアクノーレッジレジスタと同じフォーマット 以上