source: ssp_arm_gcc/trunk/target/at91skyeye_gcc/target_support.S@ 92

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

add separate package of SSP kernel for ARM + SkyEye(experimental)

File size: 10.9 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2006-2011 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 * Copyright (C) 2014,2015 by Naoki Saito
11 * Nagoya Municipal Industrial Research Institute, JAPAN
12 *
13 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
14 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
15 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
21 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
22 * の無保証規定を掲載すること.
23 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
25 * と.
26 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
27 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
28 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
29 * 報告すること.
30 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
31 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
32 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
33 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
34 * 免責すること.
35 *
36 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
37 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
38 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
39 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
40 * の責任を負わない.
41 *
42 * @(#) $Id: target_support.S 619 2014-03-18 06:10:27Z nmir-saito $
43 */
44
45/*
46 * チップ依存モジュール アセンブリ言語部(AT91SKYEYE用)
47 */
48
49#define TOPPERS_MACRO_ONLY
50#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
51#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
52
53#include "kernel_impl.h"
54
55/*
56 * 低レベルのターゲットシステム依存の初期化
57 *
58 * スタートアップモジュールの中で,メモリ初期化の前に呼び出される.
59 */
60 .text
61 .align 2
62 .global hardware_init_hook
63 .type hardware_init_hook, function
64hardware_init_hook:
65 bx lr
66
67/*
68 * 割込みハンドラ
69 *
70 * IRQ 例外ベクタから呼び出される
71 */
72 .text
73 .align 2
74 .global irq_handler
75 .type irq_handler, function
76irq_handler:
77 /*
78 * IRQモードで実行される
79 */
80 /*
81 * 割込み前のモード(スーパーバイザーモード)へ
82 * 移行し,コンテキストを保存する
83 */
84 msr cpsr_cxsf, #(CPSR_SVC | CPSR_IRQ_BIT)
85 /*
86 * コンテキストを SVモードのスタックへ保存
87 */
88 stmfd sp!, {r0-r3, ip, lr, pc} /* pcはダミー */
89
90 /*
91 * spsrと戻り番地を取得するためにIRQモードへ
92 */
93 msr cpsr_cxsf, #(CPSR_IRQ | CPSR_IRQ_BIT)
94 /* lr_irq を r0 へ */
95 sub r0, lr, #4
96 /* spsr_irq を r1 へ */
97 mrs r1, spsr
98
99 /* 割込み要因番号を r3 へ */
100 ldr r3, =AIC_IVR
101 ldr r3, [r3]
102
103 /*
104 * 割込みハンドラ実行時のモード(スーパーバイザーモード)に
105 */
106 msr cpsr_cxsf, #(CPSR_SVC | CPSR_IRQ_BIT)
107 /*
108 * 戻り番地と spsr をスーパーバイザモード用のスタックに積む
109 */
110 str r0, [sp, #0x18] /* 戻り番地をスタックに */
111 stmfd sp!, {r1} /* spsrをスタックに保存 */
112 mov lr, sp /* この時点のスタックを復帰のため取得 */
113
114 /*
115 * ネスト回数のインクリメント
116 */
117 ldr r2, =excpt_nest_count /* 例外・割込みネスト回数を取得 */
118 ldr r1, [r2]
119 add r0, r1, #1 /* 例外・割込みネスト回数を更新 */
120 str r0, [r2]
121
122irq_handler_1:
123 stmfd sp!, {lr} /* 復帰用のスタックポインタの保存 */
124
125 /*
126 * 割込み要因の割込み優先度を求め(モデル上の)割込み優先度マスクをセット
127 * する.またその際,ハンドラ実行前の(モデル上の)割込み優先度マスクを
128 * 保存する.
129 */
130 ldr r0, =inh_ipm_tbl /* 割込み優先度を取得 */
131 ldr r1, [r0, r3, lsl #2] /* r1<-割込み優先度 */
132 ldr r0, =ipm /* 割込み発生前の割込み優先度マスクをスタックに保存 */
133 ldr r2, [r0]
134 stmfd sp!,{r2}
135 str r1, [r0] /* (モデル上の)割込み優先度マスクをセット */
136
137 /*
138 * ハードウェア(IRC)は割込みを受け付けた後,割込みに応じて優先度マスク
139 * をセットする.そのためソフトウェア的には特に処理は行う必要はない.
140 * ソフトウェア的に(モデル上の)割込み優先度マスクを上げる際には,
141 * 割込み優先度マスクに応じて割込み要求禁止フラグにより割込みを禁止する.
142 */
143 /*
144 * 割込みハンドラの起動番地を取得
145 */
146 ldr r0, =inh_tbl /* 割込みハンドラテーブルの読み出し */
147 ldr r0, [r0, r3, lsl #2] /* r0<-割込みハンドラ */
148
149 stmfd sp!,{r3} /* inhno を保存 */
150
151 /*
152 * 割り込み許可
153 */
154 msr cpsr_cxsf, #(CPSR_SVC)
155
156#ifdef LOG_INH_ENTER
157 stmfd sp!,{r0}
158 mov r0, r3 /* inhno をパラメータに */
159 bl log_inh_enter /* log_inh_enterを呼び出す */
160 ldmfd sp!,{r0}
161#endif /* LOG_INH_ENTER */
162
163 /*
164 * 割込みハンドラの呼び出し
165 */
166 mov lr, pc
167 bx r0
168
169 ldmfd sp!,{r0} /* inhno を復帰 */
170#ifdef LOG_INH_LEAVE
171 bl log_inh_leave /* log_inh_leaveを呼び出す */
172#endif /* LOG_INH_LEAVE */
173
174 /*
175 * カーネル管理の割込みを禁止する
176 */
177/* msr cpsr, #(CPSR_SVC AOR CPSR_IRQ_BIT)*/
178 mrs r3, cpsr
179 and r3, r3, #CPSR_FIQ_BIT
180 orr r3, r3, #(CPSR_SVC|CPSR_IRQ_BIT)
181 msr cpsr, r3
182
183 /*
184 * 割込みクリア
185 */
186 ldr r3, =AIC_EOI
187 mov r0, #0
188 str r0, [r3]
189
190 b target_ret_int
191
192/*
193 *
194 * ターゲット依存の例外入口処理
195 *
196 */
197 .text
198 .global target_exc_handler
199 .type target_exc_handler, function
200target_exc_handler:
201 /*
202 * 前提:(1)動作モード:それぞれの例外モード(r2に種類が格納されている)
203 * (2)r1 : spsr
204 * (3)r0 : lr(割込み発生時のPCの値)
205 * (4)スタック: r0-r3,ip,lr,pc をプッシュ済み
206 * 処理:スーパーバイザーモードへ移行,割込みロック状態
207 * 割込みロック状態,CPUロック状態はCPU例外発生時の
208 * 状態を継承する.
209 */
210 msr cpsr_cxsf, #(CPSR_SVC | CPSR_FIQ_BIT | CPSR_IRQ_BIT)
211 str r0, [sp, #0x18] /* 戻り番地をスタックのPCの位置に */
212 stmfd sp!, {r1} /* spsrをスタックに保存 */
213 mov lr, sp /* この時点のスタックを復帰のため取得 */
214
215 ldr r0, =ipm /* 割込み発生前の割込み優先度マスクをスタックに保存 */
216 ldr r1, [r0]
217 stmfd sp!, {r1}
218
219 /*
220 * コンテキスト判定のため,excpt_nest_count をスタックに保存.
221 * スタックに保存せず,現在のexcpt_nest_countを-1すると取得できるが,
222 * スタックに積んでおいた方がデバッグ等が行いやすいので,スタックに
223 * 保存する.
224 */
225 ldr r0, =excpt_nest_count
226 ldr r1, [r0]
227 stmfd sp!, {r1}
228 mov r3, sp /* 例外フレーム番地を保存 */
229
230 /*
231 * ネストカウンタをインクリメント
232 */
233 ldr r0, =excpt_nest_count
234 ldr r1, [r0]
235 add r1, r1, #1
236 str r1, [r0]
237
238target_exc_handler_1:
239 stmfd sp!, {lr} /* 復帰用のスタックポインタの保存 */
240
241 /*
242 * 割込み発生前の割込み優先度マスクをスタックに保存
243 * 割込みハンドラと出口ルーチンを共有するために保存
244 */
245 ldr r0, =ipm
246 ldr r1, [r0]
247 stmfd sp!, {r1}
248
249 /*
250 * CPU例外ハンドラの起動番地を取得
251 */
252 ldr r0, =exch_tbl /* 割込みハンドラテーブルの読み出し */
253 ldr r1, [r0, r2, lsl #2] /* r1<-例外ハンドラ */
254
255 stmfd sp!,{r2} /* excno を保存 */
256
257 /*
258 * 割り込み許可
259 * CPUロック状態,割込みロック状態は継承する
260 */
261 ldr r0, [lr]
262 and r0, r0, #(CPSR_IRQ_BIT|CPSR_FIQ_BIT)
263 orr r0, r0, #(CPSR_SVC)
264 msr cpsr, r0
265
266#ifdef LOG_EXC_ENTER
267 stmfd sp!,{r1,r3}
268 mov r0, r2 /* excno をパラメータに */
269 bl log_exc_enter /* log_exc_enterを呼び出す */
270 ldmfd sp!,{r1,r3}
271#endif /* LOG_EXC_ENTER */
272
273 /*
274 * CPU例外ハンドラの呼び出し
275 * 例外フレームの先頭を引数として渡す
276 */
277 mov r0, r3
278 mov lr, pc
279 bx r1
280
281 ldmfd sp!,{r0} /* excno を復帰 */
282#ifdef LOG_EXC_LEAVE
283 bl log_exc_leave /* log_exc_leaveを呼び出す */
284#endif /* LOG_EXC_LEAVE */
285
286
287 /*
288 * カーネル管理の割込みを禁止する
289 */
290 msr cpsr_cxsf, #(CPSR_SVC | CPSR_IRQ_BIT)
291
292 /*
293 * 出口処理(ターゲット依存部)
294 * irq_handler とはここで合流する
295 */
296 .global target_ret_int
297 .type target_ret_int, function
298target_ret_int:
299 /*
300 * 割込み優先度マスクを元に戻す
301 */
302 ldmfd sp!, {r1} /* 元の割込み優先度マスクを取得 */
303 ldr r0, =ipm /* 割込み優先度マスクを復帰 */
304 str r1, [r0]
305 rsb r1, r1, #0 /* インデックスとなるように反転 */
306 ldr r0, =ipm_mask_tbl /* (モデル上)の割込み優先度のを実現するための */
307 ldr r2, [r0, r1, lsl #2] /* 割込み要求禁止フラグを取得 */
308 ldr r0, =idf /* 各割込みの割込み要求禁止フラグの状態を取得 */
309 ldr r1, [r0]
310 /*
311 * 各割込みの割込み要求禁止フラグの状態と(モデル上)の割込み優先度のを実現する
312 * ための割込み要求禁止フラグの状態のORをとり,それの否定を求めることにより,
313 * IRCの割込み許可レジスタへの設定値を生成し設定する.
314 */
315 mvn lr, #0
316 /* いったん全割込みの割込み要求をマスクする */
317 ldr r0, =AIC_IDCR
318 str lr, [r0]
319 orr r1, r1, r2 /* マスク指定されていない割込みの許可 */
320 mvn r1, r1 /* 設定値を生成 */
321 ldr r0, =AIC_IECR
322 str r1, [r0]
323
324 /*
325 * スタックポインタの復帰
326 */
327 ldmfd sp!, {r2} /* 元のスタックポインタを取得 */
328 mov sp, r2
329
330 /*
331 * 後の処理はARM依存部で実行
332 */
333 b ret_int
334
335
336/* 以降,Not Yet! */
337
338/*
339 * カーネル管理外のCPU例外の出入口処理
340 */
341 .global target_kernel_unc_exc_handler
342 .type target_kernel_unc_exc_handler, function
343target_kernel_unc_exc_handler:
344 /*
345 * ネストカウントをインクリメント
346 */
347 ldr r0, =excpt_nest_count
348 ldr r1, [r0]
349 add r1, r1, #1
350 str r1, [r0]
351
352target_kernel_unc_exc_handler_1:
353 stmfd sp!, {lr} /* 復帰用のスタックポインタの保存 */
354
355 /*
356 * CPU例外ハンドラの起動番地を取得
357 */
358 ldr r0, =exch_tbl /* 割込みハンドラテーブルの読み出し */
359 ldr r1, [r0, r2, lsl #2] /* r1<-例外ハンドラ */
360
361 /*
362 * システム状態(コンテキストは除く)を,CPU例外発生時の状態へ
363 */
364 ldr r0, [lr] /* CPU例外発生前のCPSRの取得 */
365 and r0, r0, #(CPSR_IRQ_BIT | CPSR_FIQ_BIT)
366 orr r0, r0, #(CPSR_SVC)
367 msr cpsr_cxsf, r0
368
369 /*
370 * CPU例外ハンドラの呼び出し
371 * 例外フレームの先頭を引数として渡す
372 */
373 mov r0, r3
374 mov lr, pc
375 bx r1
376
377 /*
378 * 例外・割込みのネストカウント(excpt_nest_count)のデクリメント
379 */
380 ldr r0, =excpt_nest_count /* r0 <-excpt_nest_count */
381 ldr r1, [r0]
382 sub r2, r1, #1
383 str r2, [r0]
384
385 /*
386 * スタックポインタの復帰
387 */
388 ldmfd sp!, {r2} /* 元のスタックポインタを取得 */
389 mov sp, r2
390
391 /*
392 * CPU例外からの復帰
393 */
394 ldmfd sp!,{r1} /* CPSRの復帰処理 */
395 msr spsr_cxsf, r1 /* 戻り先のcpsrをspsrに設定 */
396 ldmfd sp!,{r0-r3,ip,lr,pc}^ /* コンテキストの復帰,^付きなので、cpsr <- spsr */
Note: See TracBrowser for help on using the repository browser.