TOPPERSプロジェクト 設計メモ ルネサス RZ/AおよびGR-PEACHに関するメモ 作成者: 高田広章(名古屋大学) 最終更新: 2016年3月21日 ○メモの位置づけ このメモは,ルネサス RZ/Aと,それを用いたボードであるGR-PEACHに関して, TOPPERSカーネルをポーティングするにあたって必要となる事項をまとめたもの である. ○目次 ・参考文献 ・RZ/Aとは? ・RZ/A1チップ依存部 ○参考文献 [1] RZ/A1Hグループ,RZ/A1Mグループ ユーザーズマニュアル ハードウェア編 Rev.2.00 2015.05 r01uh0403jj0200_rz_a1h.pdf [2] RZ/A1Lグループ ユーザーズマニュアル ハードウェア編 Rev.2.00 2015.05 r01uh0437jj0200_rz_a1l.pdf ○RZ/Aシリーズとは? RZ/Aシリーズとは,ARM Cortex-A9コアを搭載したルネサスの一連のマイコンの 総称で,現時点で以下の4つのチップがある. ・RZ/A1L ・RZ/A1LU ・RZ/A1M ・RZ/A1H これらはいずれも,動作周波数400MHzのARM Cortex-A9コアを1つ搭載している が,搭載するRAM容量や周辺デバイスに違いがある. ○RZ/A1チップ依存部 TOPPERS/ASP3カーネルでは,上の4つのチップをRZ/A1と総称し(今後,RZ/A2x が出てくると想像し,RZ/A1と称している),その共通部をarch/arm_gcc/rza1 ディレクトリに置くことにする.ただし,現時点で4つのチップすべてに対応で きているわけではない. ○コア ・ARM Cortex-A9 MPCore × 1コア(Revision: r3p0) 命令キャッシュ:32KB データキャッシュ:32KB TLBエントリ:128 Jazelle,メディアプロセッシングエンジン,FPU,PTMインタフェース 内蔵の割込みコントローラは使用しない プライベートメモリ領域のベースアドレス:0xf0000000 ・内蔵のタイマは実装されている模様だが,割込みをかけることができない ○割込みコントローラ ・コア外に割込みコントローラを搭載 ・ARM PrimeCell Generic Interrupt Controller(PL390) - ARM GICアーキテクチャ仕様 バージョン1に対応 ・割込み優先順位:32レベル設定可能 ・レジスタの番地 | 0xfcfef800 ICR0 割込みコントロールレジスタ0 | 0xfcfef802 ICR1 割込みコントロールレジスタ1 | 0xfcfef804 IRQRR IRQ割込み要求レジスタ 0xe8201000 ICDDCR 分配器制御レジスタ → ディストリビュータ制御レジスタ(GICD_CTLR) …… ※ 割込みアクティブセットレジスタは,割込みアクティブビットレジスタ ※ 割込みアクティブクリアレジスタは無い | 0xe8201d00 ppi_status PPIステータスレジスタ | 0xe8201d04 spi_status0 SPIステータスレジスタ0 | …… | 0xe8201d44 spi_status16 SPIステータスレジスタ16 0xe8201f00 ICDSGIR ソフトウェア生成割込みレジスタ 0xe8202000 ICCICR CPUインタフェース制御レジスタ → CPUインタフェース制御レジスタ(GICC_CTLR) ……  割込みコントロールレジスタ0(ICR0) - NMI入力レベルの読み出し - NMIエッジセレクトの設定/読み出し - NMI割込み要求の読み出し/クリア  割込みコントロールレジスタ1(ICR1) - IRQ7〜IRQ0に対して,ローレベル,立ち下がりエッジ,立ち上がりエッ ジ,両エッジの設定/読み出し → IRQ割込みトリガ設定はこのレジスタで行い,GIC側はレベルに設定する  IRQ割込み要求レジスタ(IRQRR) - IRQ7〜IRQ0の割込み要求の読み出し/クリア ・割込み要因と割込みID - NMI割込み … CPUにFIQで通知 - IRQ割込み - 内蔵周辺モジュール割込み - 端子割込み ・IRQ割込みと内蔵周辺モジュール割込みに対して,割込みコンフィギュレーショ  ンレジスタ(GICD_ICFGRn)を指定された値に初期化する. → gic_kernel_impl.cにフックを入れることが必要 → 一括して初期化しなくても正しく動いている ○シリアルインタフェース ・RZ/A1は,FIFO内蔵シリアルコミュニケーションインタフェースを持つ RZ/A1H:8ポート RZ/A1L:5ポート ・ポート毎のレジスタ SCSMR シリアルモードレジスタ オフセット:0x00 16ビット SCBRR ビットレートレジスタ オフセット:0x04 8ビット SCSCR シリアルコントロールレジスタ オフセット:0x08 16ビット SCFTDR 送信FIFOデータレジスタ オフセット:0x0C 8ビット SCFSR シリアルステータスレジスタ オフセット:0x10 16ビット SCFRDR 受信FIFOデータレジスタ オフセット:0x14 8ビット SCFCR FIFOコントロールレジスタ オフセット:0x18 16ビット SCFDR FIFOデータカウントレジスタ オフセット:0x1C 16ビット SCSPTR シリアルポートレジスタ オフセット:0x20 16ビット SCLSR ラインステータスレジスタ オフセット:0x24 16ビット SCEMR シリアル拡張モードレジスタ オフセット:0x28 16ビット ○OSタイマ ・2チャンネルのOSタイマを持つ - 32ビットタイマ ・2つの動作モード ・P0φで駆動 - P0φは33.33MHz(最大) - ユーザーズマニュアルには33.33MHzと表記されているが,400MHzの12分 周なので,実際には,33.333333…MHzと思われる ・インターバルタイマモード - 一定間隔で割込みを発生させる場合に使用 - 指定値から0までダウンカウント(周期は,指定値+1) - 0から指定値に戻る時に割込みが発生 - 指定値を変更すると,次に戻る時に反映 - すぐに指定値を反映させることも可能 - カウント開始時に割込みを発生させる機能がある(使途が不明) - 0になった後にカウントを止めるモードはない(ワンショットはできない) ・フリーランニングコンペアモード - 0x00000000から0xffffffffまでカウントアップ - 指定値になったら,割込みが発生 - 指定値の設定時に,指定値を過ぎていた場合の対策が課題 → 読み込んで,指定値を過ぎていたら,GICを操作して割込み要求を出す ・チャネル毎のレジスタ OSTMnCMP コンペアレジスタ オフセット:0x00 RW 32ビット →「指定値」を設定 OSTMnCNT カウントレジスタ オフセット:0x04 R 32ビット OSTMnTE カウントイネーブルステータスレジスタ 0x10 R 8ビット OSTMnTS カウント開始トリガレジスタ オフセット:0x14 W 8ビット OSTMnTT カウント停止トリガレジスタ オフセット:0x18 W 8ビット OSTMnCTL 制御レジスタ オフセット:0x20 RW 8ビット → 動作モードとカウント開始時の割込みの有無を設定 ・33.33…MHzのクロックでうまくいくか? - タイマが巡回する周期を求める 2^32(= 4,294,967,296)/33.33… = 2^32(= 4,294,967,296)*3/100 = 128,849,018.88μs(約2分) → これを 128,849,019μs と丸めるのは許容範囲 この誤差は,水晶発振子の精度よりも小さい - カウンタ値 * 3 / 100 をμs単位の時刻とすると カウンタ値 μs単位時刻(カウンタ値 * 3 / 100) 0〜33 [34] 0 34〜66 [33] 1 67〜99 [33] 2 100〜133 [34] 3 … … 4294967200〜4294967233 [34] 128,849,016 4294967234〜4294967266 [33] 128,849,017 4294967267〜4294967295 [29] 128,849,018 → 最後だけ間隔が29になる → かつ,long longでの計算が必要 - (x / 4 + x / 4000000000) * 3 / 25 をμs単位の時刻とすると where x = カウンタ値 カウンタ値 μs単位時刻(カウンタ値 * 3 / 100) 0〜35 [36] 0 36〜67 [32] 1 68〜99 [32] 2 100〜135 [36] 3 136〜167 [32] 4 168〜199 [32] 5 … … 3999999900〜3999999935 [36] 119999997 3999999936〜3999999967 [32] 119999998 3999999968〜3999999999 [32] 119999999 4000000000〜4000000031 [32] 120000000 … ここが32になる 4000000032〜4000000063 [32] 120000001 4000000064〜4000000095 [32] 120000002 … … 4294967196〜4294967231 [36] 128849016 4294967232〜4294967263 [32] 128849017 4294967264〜4294967295 [32] 128849018 … 最後も32が維持される ※ 32と36の間でばらつくのは,4で割っているのでやむをえない - y = (x - z * 999999999) * 3 / 100 + z * 30000000 をμs単位の時刻とすると where x = カウンタ値, z = x / 1000000000 すべての間隔が33か34のいずれかに落ち着く ---------------------------------------------------------------------- #!/usr/bin/env ruby # -*- coding: utf-8 -*- def calc(x) # y = (x / 4 + x / 4000000000) * 3 / 25 z = x / 1000000000 y = (x - z * 999999999) * 3 / 100 + z * 30000000 return(y) end xx = yy = -1 0.upto(200).each do |x| y = calc(x) if (y != yy) if yy >= 0 puts(sprintf("%d - %d [%d] ... %d", xx, x-1, x - xx, yy)) end yy = y xx = x end end xx = yy = -1 3999999800.upto(4000000200).each do |x| y = calc(x) if (y != yy) if yy >= 0 puts(sprintf("%d - %d [%d] ... %d", xx, x-1, x - xx, yy)) end yy = y xx = x end end xl = xx = yy = -1 4294967100.upto(4294967295).each do |x| y = calc(x) if (y != yy) if yy >= 0 puts(sprintf("%d - %d [%d] ... %d", xx, x-1, x - xx, yy)) end yy = y xx = x end xl = x end puts(sprintf("%d - %d [%d] ... %d", xx, xl, xl + 1 - xx, yy)) ---------------------------------------------------------------------- 以上