source: ssp_arm_gcc/trunk/arch/arm_gcc/common/core_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: 11.0 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-2004 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2006-2012 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: core_support.S 619 2014-03-18 06:10:27Z nmir-saito $
43 */
44
45/*
46 * コア依存モジュール アセンブリ言語部(ARM用)
47 */
48
49#define TOPPERS_MACRO_ONLY
50#define TOPPERS_ASM_MACRO
51#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
52#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
53#include "kernel_impl.h"
54
55/*
56 * 例外ベクタ
57 */
58 .section vector, "a"
59 .global vector_table
60vector_table:
61 ldr pc, reset_vector /* リセット */
62 ldr pc, undef_vector /* 未定義命令 */
63 ldr pc, swi_vector /* ソフトウェア割込み */
64 ldr pc, prefech_vector /* プリフェッチアボート */
65 ldr pc, data_abort_vector /* データアボート */
66 ldr pc, reset_vector
67 ldr pc, irq_vector /* IRQ */
68 ldr pc, fiq_vector /* FIQ */
69
70/*
71 * 例外ベクタの命令から参照される
72 * ジャンプ先アドレス
73 */
74 .global vector_ref_tbl
75vector_ref_tbl:
76reset_vector:
77 .long start
78undef_vector:
79 .long undef_handler
80swi_vector:
81 .long swi_handler
82prefech_vector:
83 .long prefetch_handler
84data_abort_vector:
85 .long data_abort_handler
86irq_vector:
87 .long irq_handler
88fiq_vector:
89 .long fiq_handler
90
91/*
92 * タスクディスパッチャ
93 */
94 .text
95 .align 2
96/*
97 * ディスパッチャの動作開始
98 */
99 .global start_dispatch
100 .type start_dispatch, function
101start_dispatch:
102 /*
103 * このルーチンは,カーネル起動時に,すべての割込みを禁止した状態
104 * (割込みロック状態と同等)で呼び出される.また,割込みモード(非
105 * タスクコンテキストと同等)で呼び出されることを想定している.
106 *
107 * dispatcherは,CPUロック状態,(モデル上の)割込み優先度マスク全
108 * 解除状態,例外(割込み/CPU例外)のネスト回数0で呼び出す.
109 * target_initializeでは,(モデル上の)割込み優先度マスク全解除
110 * とし,カーネル管理外の割込みであるFIQを許可することで,
111 * CPUロック状態・(モデル上の)割込み優先度マスク全解除状態になる.
112 * また,initialize_taskでdisdspをfalseに初期化しているため,ディ
113 * スパッチ許可状態になっている.
114 *
115 */
116 msr cpsr_cxsf, #(CPSR_SVC | CPSR_CPULOCK | CPSR_ALWAYS_SET) /* CPUロック状態へ */
117 ldr r2, =excpt_nest_count /* 例外(割込み/CPU例外)のネスト回数を0に */
118 mov r0, #0
119 str r0, [r2]
120 ldr r0, =_kernel_istkpt /* スタックポインタを初期化(戻ってこないので) */
121 ldr sp, [r0]
122 b dispatcher
123
124
125/*
126 * カーネルの終了処理の呼出し
127 *
128 * モードとスタックを非タスクコンテキスト用に切り替え.
129 */
130 .global call_exit_kernel
131 .type call_exit_kernel, function
132call_exit_kernel:
133 msr cpsr_cxsf, #(CPSR_SVC | CPSR_ALWAYS_SET | CPSR_IRQ_BIT | CPSR_FIQ_BIT)
134 ldr r0, =_kernel_istkpt /* スタックポインタを初期化 */
135 ldr sp, [r0]
136 b exit_kernel
137
138/*
139 * 割込みハンドラ/CPU例外ハンドラ出口処理
140 *
141 * ret_intは,割込みハンドラから戻った直後に実行するルーチンで,
142 * 割込みハンドラ終了後,ターゲット依存の処理を実行した後,
143 * カーネル管理の割込みを禁止,スタックを割込み前のスタックにした
144 * 状態で呼び出される.
145 */
146 .text
147 .global ret_int
148 .type ret_int, function
149 .global ret_exc
150 .type ret_exc, function
151ret_int:
152ret_exc:
153 /*
154 * 例外・割込みのネストカウント(excpt_nest_count)のデクリメント
155 */
156 ldr r0, =excpt_nest_count /* r0 <-excpt_nest_count */
157 ldr r1, [r0]
158 sub r2, r1, #1
159 str r2, [r0]
160 cmp r2, #0 /* 戻り先が非タスクコンテキストなら */
161 bne ret_int_1 /* すぐにリターン */
162
163 /*
164 * reqflgをチェックする前に割込みを禁止するのは,reqflgをチェック
165 * した直後に割込みハンドラが起動され,その中でディスパッチが要求
166 * された場合に,すぐにディスパッチされないという問題が生じるため
167 * である.
168 */
169 ldr r0, =reqflg
170 ldr r1, [r0]
171 cmp r1, #0 /* reqflgがtrueであればret_int_2へ */
172 bne ret_int_2
173
174ret_int_1:
175 /*
176 * 割込み処理からのリターンにより,CPUロック解除状態に移行しなければ
177 * ならない.
178 * ARMでは,CPSRのIRQビットでCPUロック解除状態とするため,単にリターン
179 * すればよい.
180 */
181 ldmfd sp!, {r1} /* CPSRの復帰処理 */
182 msr spsr_cxsf, r1 /* 戻り先のcpsrをspsrに設定 */
183 ldmfd sp!, {r0-r3,ip,lr,pc}^ /* コンテキストの復帰,^付きなので、cpsr <- spsr */
184
185ret_int_2:
186ret_int_3:
187 /*
188 * ここへは,CPU例外ハンドラの出口処理からも分岐してくる.
189 *
190 * ここでは,戻り先がタスクであり,スタックは,タスクスタックの上
191 * にスクラッチレジスタのみが保存された状態になっている.また,
192 * プロセッサは,スーパーバイザーモード・カーネル管理の割込みを禁止
193 * した状態となっている.
194 */
195 ldr r0, =reqflg /* reqflgをfalseに */
196 mov r1, #0
197 str r1, [r0]
198
199 /*
200 * CPUロック状態に移行し,割込み優先度マスクを割込み処理前の値に
201 * 設定する.
202 *
203 * この時点でCPUロック状態とするのは,dispatcherへ分岐する時と,
204 * call_texrtnを呼び出す時に,CPUロック状態になっている必要がある
205 * ためである.
206 *
207 * CPUロック状態に関しては,ARMでは,CPSRのIRQビットでCPUロック
208 * 状態を表現するため,ここでは,特に何も行わない.
209 *
210 * 割込み優先度マスクに関しては,ターゲット毎に操作が異なるため,
211 * 割込みハンドラ終了直後にターゲット依存部で割込み処理前の値に
212 * 設定する.
213 */
214
215 /*
216 * disdsp が trueである場合には,ディスパッチを行わない.
217 */
218 ldr r0, =disdsp
219 ldr r2, [r0]
220 cmp r2, #0 /* disdsp がtrueならret_int_4へ */
221 bne ret_int_4
222
223 /*
224 * ディスパッチ
225 */
226 /*** タスク起動は関数呼び出しなので,r4-r11 の保存/復帰は必要ないかもしれない ***/
227 stmfd sp!, {r4-r11} /* 残りのレジスタを保存 */
228
229 /* CPUロック状態にしておく */
230 msr cpsr, #(CPSR_SVC | CPSR_IRQ_BIT)
231
232 /* 最高優先タスクをサーチして,タスク起動 */
233 bl _kernel_search_schedtsk
234 bl _kernel_run_task
235
236 ldmfd sp!, {r4-r11} /* レジスタの復帰 */
237
238ret_int_4:
239 /*
240 * 割込み処理からのリターンにより,CPU ロック解除状態に移行するよ
241 * うにする.ARM は CPSR の IRQ ビットによって CPU ロック状態を表してい
242 * るため,そのままリターンすればよい.
243 */
244 ldmfd sp!, {r0} /* spsr を復帰 */
245 msr spsr,r0 /* 戻り先のcpsrをspsrに設定 */
246 ldmfd sp!,{r0-r3,ip,lr,pc}^ /* タスクに復帰 ^付きなので、cpsr <- spsr */
247
248
249/*
250 * CPU例外ハンドラ
251 *
252 * CPU例外ハンドラは,非タスクコンテキストで実行する.
253 *
254 */
255
256/*
257 * 未定義命令 例外ハンドラ
258 */
259 .text
260 .align 2
261 .global undef_handler
262 .type undef_handler, function
263undef_handler:
264 /*
265 * タスクの動作時モード(スーパーバイザーモード)へ
266 */
267 msr cpsr_cxsf, #(CPSR_SVC | CPSR_CPULOCK | CPSR_ALWAYS_SET)
268 stmfd sp!, {r0-r3,ip,lr,pc} /* pcはダミー */
269
270 /*
271 * spsrと戻り番地を取得するために未定義モードへ
272 */
273 msr cpsr_cxsf, #(CPSR_UND | CPSR_CPULOCK | CPSR_ALWAYS_SET)
274 mov r0, lr
275 mrs r1, spsr
276 mov r2, #EXCH_NO_UNDEF
277 b target_exc_handler
278
279
280/*
281 * SWI 例外ハンドラ
282 */
283 .text
284 .align 2
285 .global swi_handler
286 .type swi_handler, function
287swi_handler:
288 /*
289 * タスクの動作時モード(スーパーバイザーモード)へ
290 * 元々スーパーバイザーモードだが,CPUロック状態とする
291 */
292 msr cpsr_cxsf, #(CPSR_SVC | CPSR_CPULOCK | CPSR_ALWAYS_SET)
293 stmfd sp!, {r0-r3,ip,lr,pc} /* pcはダミー */
294 mov r0, lr
295 mrs r1, spsr
296
297
298 mov r2, #EXCH_NO_SVC
299 b target_exc_handler
300
301
302/*
303 * プリフェッチアボード 例外ハンドラ
304 */
305 .text
306 .align 2
307 .global prefetch_handler
308 .type prefetch_handler, function
309prefetch_handler:
310 /*
311 * タスクの動作時モード(スーパーバイザーモード)へ
312 */
313 msr cpsr_cxsf, #(CPSR_SVC | CPSR_CPULOCK | CPSR_ALWAYS_SET)
314 stmfd sp!, {r0-r3,ip,lr,pc} /* pcはダミー */
315
316 /*
317 * spsrと戻り番地を取得するためにアボートモードへ
318 */
319 msr cpsr_cxsf, #(CPSR_ABT | CPSR_CPULOCK | CPSR_ALWAYS_SET)
320 mov r0, lr
321 mrs r1, spsr
322 mov r2, #EXCH_NO_PABORT
323 b target_exc_handler
324
325
326/*
327 * データアボード 例外ハンドラ
328 */
329 .text
330 .align 2
331 .global data_abort_handler
332 .type data_abort_handler, function
333data_abort_handler:
334 /*
335 * タスクの動作時モード(スーパーバイザーモード)へ
336 */
337 msr cpsr_cxsf, #(CPSR_SVC | CPSR_CPULOCK | CPSR_ALWAYS_SET)
338 stmfd sp!, {r0-r3,ip,lr,pc} /* pcはダミー */
339
340 /*
341 * spsrと戻り番地を取得するためにアボートモードへ
342 */
343 msr cpsr_cxsf, #(CPSR_ABT | CPSR_CPULOCK | CPSR_ALWAYS_SET)
344 mov r0, lr
345 mrs r1, spsr
346 mov r2, #EXCH_NO_DABORT
347 b target_exc_handler
348
349
350#ifndef TARGET_FIQ_HANDLER
351/*
352 * FIQ 例外ハンドラ
353 */
354 .text
355 .align 2
356 .global fiq_handler
357 .type fiq_handler, function
358fiq_handler:
359 /*
360 * タスクの動作時モード(スーパーバイザーモード)へ
361 */
362 msr cpsr_cxsf, #(CPSR_SVC | CPSR_FIQ_BIT | CPSR_CPULOCK | CPSR_ALWAYS_SET)
363 stmfd sp!, {r0-r3,ip,lr,pc} /* pcはダミー */
364
365 /*
366 * spsrと戻り番地を取得するためにFIQモードへ
367 */
368 msr cpsr_cxsf, #(CPSR_FIQ | CPSR_FIQ_BIT | CPSR_CPULOCK | CPSR_ALWAYS_SET)
369 mov r0, lr
370 mrs r1, spsr
371 mov r2, #EXCH_NO_FIQ
372 b target_exc_handler
373#endif /* TARGET_FIQ_HANDLER */
374
375/*
376 * 微少時間待ち
377 */
378 .global _sil_dly_nse
379 .type _sil_dly_nse, function
380_sil_dly_nse:
381 sub r0, r0, #SIL_DLY_TIM1
382 cmp r0, #0
383 bgt _sil_dly_nse1
384 bxle lr
385_sil_dly_nse1:
386 sub r0, r0, #SIL_DLY_TIM2
387 cmp r0, #0
388 bgt _sil_dly_nse1
389 bxle lr
390
391#ifdef __thumb__
392 .text
393 .align 2
394 AWEAK(current_sr)
395current_sr:
396 mrs r0, cpsr
397 bx lr
398
399 .weak set_sr
400set_sr:
401 msr cpsr_cxsf, r0
402 bx lr
403#endif /* __thumb__ */
Note: See TracBrowser for help on using the repository browser.