source: ssp_rpi3/trunk/arch/arm64_gcc/common/core_design.txt@ 386

Last change on this file since 386 was 386, checked in by nmir-saito, 5 years ago

modify svn:mimetype of files

  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/plain; charset=utf-8
File size: 15.6 KB
Line 
1=====================================================================
2 ARM64プロセッサ依存部設計メモ
3 Last Modified: 16 Apr 2019
4=====================================================================
5
6○ このドキュメントの位置づけ
7
8このドキュメントは,TOPPERS/SSPカーネルをARMv8-Aプロセッサに移植する際
9の設計メモである.
10
11
12○ ARMv8-Aの仕様まとめ
13
14ARMv8-Aの仕様のうち,カーネルの設計に関係する事項についてまとめる.
15
16● レジスタ
17
18汎用レジスタはr0〜r30 (特に64ビットレジスタはX0..X30で表現)の31種類からなる.
19(参考)「Procedure Call Standard for the ARM 64-bit Architecture」
20
21r0...r7 Parameter/result registers(引数および返値の受け渡し用)
22r8 Indirect result location register (大きなデータ構造を
23 返値として返す場合など,呼び出し側が結果を取り出すために
24 間接アドレッシングを多用する際,そのベースアドレスを受け渡し
25 するために使われる)
26r9..r15 Caller-saved Temporary registers(呼び出し側で保存すべきレジスタ)
27r16(IP0) The first intra-procedure-call scratch register
28 リンカによって veneer(注1) および PLT(Procedure Linkage Table,注2) コード
29 の呼び出しで使われる.それ以外の時はテンポラリレジスタとして使われることもある.
30 (注1)リンカによって挿入される小さなコード片で,
31 分岐命令のターゲットが範囲外の場合などに使われる
32 (注2)共有ライブラリの呼び出しでシンボル解決を行うために使用される
33 関数テーブル
34r17(IP1) The second intra-procedure-call temporary register(r16と役割は同じ)
35r18 The Platform Register(プラットフォームABIで使用されるレジスタ.
36 ABIで使われない場合はテンポラリレジスタとして使われる)
37r19..r28 Callee-saved registers(呼び出された側で保存して使うレジスタ)
38r29(FP) The Frame Pointer(フレームポインタ)
39r30(LR) The Link Register(リンクレジスタ)
40
41SSPカーネルのアセンブラによる実装ではr8, r16...r18は使用していない.
42
43
44● コーリングコンベンション
45
46r0...r7 が引数および返値に使われる.
47ARMにより規定されているため,コンパイラに依存せずこのルールとなる
48
49
50● PSTATE
51
52AArch64ではプロセッサの状態を表すフラグの集まりをまとめてPSTATEと呼び,
53それぞれのフラグへ別々にアクセスするための特別なレジスタ名が定義されている.
54
55PSTATEの詳細は,ARM Architecture Reference Manual
56ARMv8, for ARMv8-A architecture profile の D1.7 などを参照のこと.
57
58・spsel
59EL1より上の例外レベルでは,spsel という特別な名称のレジスタにアクセスし,
60PSTATE.SPフラグの値をセットして使用スタックの切り替えを行う.
61
62・daif
63daif という名称のレジスタを使用してPSTATEのD,A,I,Fビットを操作し,
64各種例外および割込みの禁止/許可を制御する
65
66
67SSPカーネルの実装では,スタックはSP_EL1のみを使用する.
68また,CPUロック状態および割込みロック状態の実装にPSTATEのIおよびFフラグを
69利用している.
70
71
72● 割込みベクタ
73
74ベクタテーブルのアドレスはリセット時に,システムレジスタの一つVector Base
75Address Register(VBAR, システムレジスタ)にアドレスをセットすることで,
762048バイト境界の任意のアドレスに配置可能である.
77
78SSPカーネルの実装ではスタートアップルーチンで設定している.
79
80
81● 割込み
82
83ここではGICを搭載するプロセッサの場合について述べる.
84それ以外の場合についてはチップ依存部のドキュメントに記載する.
85
86
87●割込み優先度
88
89GICにおいては割込み優先度は設定値の小さい方が高優先度となる.
90
91優先度は最大8bitであり,SoC毎に実装されているビット幅が異なる.実装さ
92れるビットが8bit以下の場合は,LSBから無効になる.例えば,実装されてい
93るビット幅が7bitの場合は,ビット0が無効となる.
94
95優先度のビットフィールドのLSBから数ビットをサブ優先度と呼ぶフィールド
96に設定することが可能である.残りの上位ビットをプリエンプション優先度と
97呼ぶ.プリエンプション優先度が同じで,サブ優先度が異なる優先度のグルー
98プは,お互いをプリエンプトすることができない.
99
100例として,QEMU Virtボード向けSSPの実装では Cortex-A53プロセッサを
101ターゲットとしており,優先度は16段階(4bit)でビット0から3が無効である.
102
103●割込み/例外の受付
104
105GICの場合,割込みを受け付けると受け付けた割込みの番号がGICC_IARにセットされる.
106割込み番号はこのレジスタにセットされる値を使用する.
107
108例外番号は,例外発生時のプロセッサ状態に応じて決定される,ベクタテーブル中の
109ジャンプ先オフセット毎に異なる番号を割り振ることにしている.
110
111 例外発生時の状態 例外の種類 例外番号  例外ベクタ先頭からのオフセット
112 AArch64, EL1t(EL1, SP_EL0) Synchronous 0 0x0000
113 AArch64, EL1t(EL1, SP_EL0) SError 1 0x0180
114 AArch64, EL1h(EL1, SP_EL1) Synchronous 2 0x0200
115 AArch64, EL1h(EL1, SP_EL1) SError 3 0x0380
116 AArch64, EL0 (EL0, SP_EL0) Synchronous 4 0x0400
117 AArch64, EL0 (EL0, SP_EL0) SError 5 0x0580
118 AArch32, EL0 (EL0, SP_EL0) Synchronous 6 0x0600
119 AArch32, EL0 (EL0, SP_EL0) SError 7 0x0780
120
121割込みを受け付けた際,受け付けた割込みに設定された優先度より低い割込みを
122禁止するため,GICC_RPRから取得した割込み要因の割込み優先度を GICC_PMRへ
123セットしている.そしてハンドラ終了後に割込み発生前の割り込み優先度に戻す.
124
125
126[CPUモード]
127
128プロセッサは,EL0からEL3までの例外レベルのいずれかで動作する.
129またそれぞれのレベルで64ビットモード(AArch64) または32ビットモード(AArch32)を
130選択することができる.ただし,ある例外レベルが32ビットモードで動作する場合は
131それより低い例外レベルでは64ビットモードを選択することができない.
132
133また,セキュリティ拡張機能を搭載するプロセッサではセキュアモードおよび
134非セキュアモードを選択することができる.
135
136SSPの実装では,64ビットモード(AArch64),非セキュア,例外レベル1(EL1) で動作する.
137
138
139●リセット時の状態
140
141リセット時はプロセッサチップがサポートする最大の例外レベルおよびそのレベルの
142スタック(SP_ELx)が有効となっている.
143
144例としてQEMU向けVirtボード(Cortex-A53) では,既定でEL1が最大例外レベルのため
145リセット直後はSP_EL1が有効となっている.
146
147
148● スタックポインタ(SP_EL0とSP_ELx)
149
150スタックポインタは,例外レベル0のスタックポインタ(SP_EL0)および実行中の
151例外レベルのスタックポインタ(SP_ELx)が選択可能である.
152スタックの選択はspselレジスタへ1を設定するとSP_ELxを,0を設定すると
153SP_EL0 を選択する.
154
155SSPの実装では,EL1 で SP_EL1 のみを使用して動作する.
156
157
158●例外レベルの遷移
159
160例外レベル(EL)の遷移は割込み/例外の受付および例外リターン命令(eret)により行う.
161
162割込みおよび例外を受け付けることで発生前と同じまたはより高い例外レベルへ遷移する.
163一方,同じまたはより低い例外レベルへの遷移は例外リターン命令(eret)により行う.
164
165受付時の遷移先となる例外レベルの指定はシステムレジスタにより設定することで行う.
166割込み/例外リターン時の遷移先となる例外レベルは,SPSR_ELxのビット2および3で
167指定する.割込み/例外受付時,PSTATEの状態がSPSR_ELxに,リターンアドレスがELR_ELxに,
168それぞれ保存されeret命令の実行によりその格納値が復帰されるため,eret実行前に
169あらかじめSPSR_ELxにセットしておくことで指定した例外レベルへ遷移することが可能である.
170同じタイミングで使用スタックや64ビット/32ビットモードの指定も行うことができる.
171
172QEMU Virt向けSSPの実装ではEL1のみを使用するため,例外レベル間の遷移処理は行っていない.
173
174
175●例外レベルの判定
176
177現状の例外レベルを判定するには,CPSRのビット2およびビット3の値を使用する.
178bit[3:2]の値が
179 '11'の場合:EL3
180 '10'の場合:EL2
181 '01'の場合:EL1
182 '00'の場合:EL0
183
184●GICC_PMRレジスタ
185
186設定した優先度以下(値としては以上)の優先度の割込みの受付を禁止する.
187設定可能な最大値を設定すると,全ての割込みを許可する.
188例えば優先度が16段階の場合は0xf0(=0x0f << 4)をセットするとすべての割込み許可
189となる.値は例外/割込みの受付とリターンにより変化しないため,受け付けた割込み
190の優先度を割込みの入口処理で設定する必要がある.
191
192●例外/割込みの受付
193
194・例外/割込みを受付けると,受付け時にアクティブなスタック上に以下のコ
195 ンテキストを保存する.
196
197 --------------- <- new SP
198 | GICC_PMR |
199 ----------------
200 | 割込み/例外番号|
201 ----------------
202 | ESR_ELx |
203 ----------------
204 | ELR_ELx |
205 ----------------
206 | SPSR_ELx |
207 ----------------
208 | X30 |
209 ----------------
210 | X29 |
211 ----------------
212 | : |
213 | : |
214 ----------------
215 | X1 |
216 ----------------
217 | X0 |
218 ---------------- <- old SP
219 | |
220
221
222割込み/例外発生時の主なシーケンスは次のようになる(遷移先の例外レベルをELxと表現する)
223
224(ハードウェアの処理)
225 ・PSTATEをSPSR_ELxに保存する
226 ・リターンアドレスをELR_ELxに保存する
227 ・PSTATE.{D,A,I,F}を1にセットする
228 ・同期例外およびSError割込みのとき,例外要因情報をESR_ELxに保存する
229 ・スタックポインタをSP_ELxに切り替える
230 ・ELxへ遷移する
231
232(ソフトウェアでの処理)
233 ・(発生時にSP_EL0を使用していた場合)スタックを割込み発生前(SP_EL0)に戻す
234 ・汎用レジスタ(X0-X30)をスタックに保存
235 ・SPSR_ELx, ESR_ELx, ELR_ELxをスタックに保存
236 ・スタックポインタのアライメントを調整
237 ・割込み番号(GICC_IARから取得),例外番号(オフセット毎に定義した値)をスタックに保存
238 ・割込み発生前の割込み優先度マスクをスタックに保存
239 ・GICC_PMRに受け付けた割込みの割込み優先度をセット
240 ・割込み/例外ネストカウンタのインクリメント
241 ・(割込みの場合)CPUロック解除
242 ・ベクタテーブルを読み込みハンドラを実行する
243
244●例外/割込みからのリターン
245
246(ソフトウェアでの処理)
247 ・CPUロック状態へ移行
248 ・割込み/例外ネスとカウンタのデクリメント
249 ・GICC_PMRに割込み発生前の優先度マスクを戻す
250 ・スタックポインタのアライメント調整分を戻す
251 ・戻り先のコンテキストやシステム状態に応じて割込み/例外発生元へリターン
252 または遅延ディスパッチを実行する
253 ・ELR_ELxに戻り先アドレス,SPSR_ELxにプロセッサ状態がそれぞれ
254 セットされている状態でeret命令を実行し,割込み/例外からリターン
255
256
257○OSの実装
258
2591.コア依存部名称: arm64
260
261ARMv8 では,64ビットモード(AArch64)および32ビットモード(AArch32)の両方をサポートするが
262本実装は64ビットモードのみをサポートすることを明示するためプロセッサ依存部名称を arm64 とした
263
2642. 例外モードの使い分け
265
266本実装ではタスクコンテキスト,非タスクコンテキストいずれも例外レベル1(EL1)で動作する.
267タスクコンテキストをEL0で動作する案も考えられる.その場合は割込み/例外の出口処理において
268遅延ディスパッチの前に例外レベルの切り替えが必要となる.
269
2703.ディスパッチャの実行モード
271
272本実装ではすべて例外レベル1で動作するため,ディスパッチャは例外レベル1(EL1)で動作する.
273
274
2754.スタックの使い分け
276
277SSPではタスクコンテキスト,非タスクコンテキスト共に一つのスタックを共用する.
278本実装ではSP_ELxを使用している.
279この他にSP_EL0を使用する実装も考えられる.その場合は割込み/例外の入口処理にて
280レジスタを保存する前にSP_EL0へのスタック切り替えを行う.
281
2825.コンテキストの判定
283
284割込み/例外のネスト回数を保持する変数(intnest)が0ならタスクタスクコンテキスト,
2851以上なら非タスクコンテキストとする.
286コンテキスト毎に例外レベルを分ける実装を取る場合はPSTATEのビット2および3で
287例外レベルを読み出すことにより判別するという方法も考えられる.
288本実装ではコンテキストによらず同じ例外レベルを使用し,プロセッサの
289ステータスレジスタでは判別ができないため変数で判別する.
290
2916. CPUロック
292
293CPUロックPSTATE.IによりCPUロックを実現する.
294
2957. 割込みロックとCPU例外の関係
296
297FIQをカーネル管理外の割込みとするため,割込みロックはPSTATE.Iに加えて
298PSTATE.Fも用いて実現する.ただし,フラグをお互いに独立させるため,
299割込みロック状態の設定/解除の際は,ロック前にCPUロックフラグ(=PSTATE.I)の
300状態を保存し,解除前に元の状態に戻すようにしている.
301
3028. 外部優先度と内部優先度
303
304外部優先度とはAPIで指定する割込み優先度(PRI型)のことであり,値が小さい
305ほど優先度が高い.割込みハンドラには,-1から連続した負の値を設定可能で
306ある.GICの場合,内部優先度は,GICC_PMRレジスタに設定する値である.
307外部優先度と内部優先度の変換は以下のマクロで表現される.
308
309/* 外部表現への変換 */
310#define EXT_IPM(pri) \
311 (((PRI)((pri) >> GIC_PRI_SHIFT)) - (GIC_PRI_LEVEL - 1))
312
313/* 内部表現への変換 */
314#define INT_IPM(ipm) \
315 (((uint_t)((ipm) + (GIC_PRI_LEVEL - 1))) << GIC_PRI_SHIFT)
316
317ここでGIC_PRI_LEVELはサポートする割込み優先度の数,GIC_PRI_SHIFTはGICC_PMRレジスタ内
318の,内部優先度の値が格納される位置(ビット0からのオフセット)を表す.
319
320
3219. カーネル管理内の最高優先度(CPUロック状態での優先度マスク)
322
323GICの場合,カーネル管理内の割込みの最高優先度は設定可能な外部優先度の最高値と同じとする.
324
325
326以上.
Note: See TracBrowser for help on using the repository browser.