source: ssp_qb_r5f100le_cs/trunk/arch/arm_m_gcc/prc_support.S@ 95

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

ファイルの mime-type 変更

  • Property svn:mime-type set to text/plain; charset=shift_jis
File size: 10.9 KB
Line 
1/*
2 * TOPPERS/SSP Kernel
3 * Smallest Set Profile Kernel
4 *
5 * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
6 * Graduate School of Information Science, Nagoya Univ., JAPAN
7 * Copyright (C) 2010 by Meika Sugimoto
8 *
9 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
10 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
12 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14 * スコード中に含まれていること.
15 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18 * の無保証規定を掲載すること.
19 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
21 * と.
22 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
23 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
24 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
25 * 報告すること.
26 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
27 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
28 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
29 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
30 * 免責すること.
31 *
32 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
34 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
35 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
36 * の責任を負わない.
37 *
38 */
39
40/*
41 * プロセッサ依存モジュール アセンブリ言語部(ARM-M用)
42 */
43
44#define TOPPERS_MACRO_ONLY
45#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
46#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
47#define CAST(type, val) (val) /* 型キャストを行うマクロ */
48
49#include "kernel_impl.h"
50#include "arm_m.h"
51
52
53 .text
54
55/*
56 * 外部参照
57 */
58 .global intnest
59
60/*
61 * CPU例外エントリ
62 *
63 * 割込みエントリと処理の内容は同等だが,ログの種類が異なるため,
64 * 分けている.
65 */
66 .align 2
67 .syntax unified
68 .code 16
69 .global exc_entry
70 .type exc_entry, function
71exc_entry:
72 /*
73 * 例外/割込みが発生すると,発生時にアクティブなスタックにスクラ
74 * ッチレジスタ等が保存される.
75 * この内容に加えて,CPU例外ハンドラへの情報として,basepri の値と,
76 * EXC_RETURNの情報を加えて保存する.basepriの値は,CPU例外からの
77 * リターン時に割込み優先度マスクの値を元に戻すためにも用いられる.
78 *
79 * -----------
80 * | EXC_RETURN|
81 * -----------
82 * | basepri |
83 * -----------
84 * | R0 |
85 * -----------
86 * | R1 |
87 * -----------
88 * | R2 |
89 * -----------
90 * | R3 |
91 * -----------
92 * | R12 |
93 * -----------
94 * | LR |
95 * -----------
96 * | PC |
97 * -----------
98 * | xPSR |
99 * -----------
100 *
101 */
102
103 /*
104 * 割込み発生時の割込み優先度マスクをスタックに保存するため取得
105 */
106 mrs r2, basepri /* baepriの値を取得 */
107 push {r2} /* 割込み発生時の割込み優先度マスクを積む */
108 push {lr} /* EXC_RETURN を積む */
109 mov r0, sp /* CPU例外ハンドラへの引数となる */
110
111 ldr r1 , =lock_flag /* CPUロックフラグを保存 */
112 ldr r1 , [r1]
113 push {r1}
114
115 /* 割込みネスト数の加算 */
116 ldr r1 , =intnest
117 ldr r3 , [r1]
118 add r3 , #1
119 str r3 , [r1]
120
121 /*
122 * 共通処理
123 */
124exc_entry_2:
125 mrs r3, ipsr /* ハンドラアドレスを取得 */
126 ldr r1, =_kernel_exc_tbl
127 ldr r2, [r1, r3, lsl #2]
128
129#ifdef LOG_EXC_ENTER
130 push {r0, r2, r3}
131 mov r0, r3 /* 例外番号をパラメータに */
132 bl log_exc_enter /* log_exc_enterを呼び出す */
133 pop {r0, r2, r3}
134#endif /* LOG_EXC_ENTER */
135
136#ifdef LOG_EXC_LEAVE
137 push { r3 } /* 例外番号をスタックへ */
138#endif /* LOG_EXC_LEAVE */
139
140 /*
141 * CPU例外ハンドラの呼び出し
142 */
143 blx r2
144
145 /* CPUロックフラグを元に戻す */
146 pop {r0}
147 ldr r1 , =lock_flag
148 str r0 , [r1]
149
150#ifdef LOG_EXC_LEAVE
151 pop { r0 } /* 例外番号を引数に */
152 bl log_exc_leave /* log_exc_leaveを呼び出す */
153#endif /* LOG_EXC_LEAVE */
154
155 b ret_exc
156
157
158/*
159 * 割込みエントリ
160 */
161 .align 2
162 .syntax unified
163 .code 16
164 .global int_entry
165 .type int_entry, function
166int_entry:
167 /*
168 * 割込み発生時の割込み優先度マスクをスタックに保存するため取得
169 */
170 mrs r2, basepri /* baepriの値を取得 */
171 push {r2} /* 割込み発生時の割込み優先度マスクを積む */
172 push {lr} /* EXC_RETURN を積む */
173 mov r0, sp /* 未定義の割込みが発生した場合の情報とする */
174
175 /*
176 * 共通処理
177 */
178int_entry_2:
179 /* 割込みネスト数の加算 */
180 ldr r1 , =intnest
181 ldr r3 , [r1]
182 add r3 , #1
183 str r3 , [r1]
184
185 mrs r3, ipsr /* ハンドラアドレスを取得 */
186 ldr r1, =_kernel_exc_tbl
187 ldr r2, [r1, r3, lsl #2]
188
189#ifdef LOG_INH_ENTER
190 push {r0,r2,r3}
191 mov r0, r3 /* 割込み番号をパラメータに */
192 bl log_inh_enter /* log_inh_enterを呼び出す */
193 pop { r0,r2,r3 }
194#endif /* LOG_INH_ENTER */
195
196#ifdef LOG_INH_LEAVE
197 push { r3 } /* 割込み番号をスタックへ */
198#endif /* LOG_INH_LEAVE */
199
200 /*
201 * CPU例外ハンドラの呼び出し
202 */
203 blx r2
204
205#ifdef LOG_INH_LEAVE
206 pop { r0 } /* 割込み番号を引数に */
207 bl log_inh_leave /* log_inh_leaveを呼び出す */
208#endif /* LOG_INH_LEAVE */
209
210/*
211 * 割込み/例外出口
212 *
213 * ret_exc/ret_intは,CPU例外/割込みハンドラから戻った直後に実行する
214 * ルーチンである.
215 */
216ret_exc:
217ret_int:
218 /*
219 * 割込みロック状態とする.この時点では,CPUロック状態にはならない
220 * (basepriとlock_flagとsaved_iipmは更新しない).
221 *
222 * 割込みロック状態とするのは,戻り先のコンテキストのチェックと,
223 * 戻り先が非タスクコンテキストであった場合のリターンをアトミック
224 * に行うためである.bsepriをCPUロックの値にすることでもアトミッ
225 * クなチェックと復帰は可能であるが,割込みからリターンしても,
226 * basepri の設定内容は元に戻らないため,使用することができない.
227 * 一方,FAULTMASKは,割込みからのリターン処理によって,'0'にクリ
228 * アされる.
229 */
230 cpsid f
231
232 /*
233 * 戻り先のコンテキストの判定
234 *
235 * intnestが0かどうかで判断する
236 *
237 */
238 /* 割込みネスト数の減算 */
239 ldr r1 , =intnest
240 ldr r3 , [r1]
241 add r3 , #-1
242 str r3 , [r1]
243
244 cmp r3 , #0
245 beq ret_int_2
246
247 /*
248 * 一段目の割込みの出口処理
249 */
250ret_int_1:
251 /*
252 * ここには割込みロック状態(FAULTMASKがセット)された状態で来る.
253 * Threadモードからのリターンにより自動的に割込みロック解除状態になる.
254 * 割込み優先度マスクは割込み前に状態に戻す.
255 */
256 pop { r2 }
257 pop { r1 }
258 msr basepri, r1 /* 割込み優先度マスクを割込み前に状態へ */
259 bx r2 /* リターン */
260
261ret_int_2:
262 ldr r0, =reqflg /* reqflgがfalseならそのまま戻る */
263 ldr r1, [r0]
264 cmp r1 , #0
265 beq ret_int_1 /* falseならret_int_1へ */
266ret_int_3:
267 mov r1, #0 /* reqflgをfalseに */
268 str r1, [r0]
269
270 /*
271 * CPUロック状態に移行する.
272 *
273 * カーネルの管理内の割込みを禁止するようにbasepriを設定し,
274 * lock_flagを更新する.
275 * この時点でCPUロック状態とするのは,dispatcherへ分岐する時に
276 * CPUロック状態になっている必要があるためである.
277 * なお,この処理の後,Threadモードへの移行処理を行なうため,割込み
278 * ロック状態(FAULTMASKを"1")は保持する.
279 */
280 ldr r1, =IIPM_LOCK /* CPUロック状態 */
281 msr basepri, r1
282 mov r1, #0x01 /* lock_flag を trueに */
283 ldr r0, =lock_flag
284 str r1, [r0]
285
286 /*
287 * lrを取り出す.ただし遅延ディスパッチの際にも使うため,
288 * スタックポインタは操作しない.
289 */
290
291 ldr r2 , [sp]
292
293 /*
294 * Threadモードへ移行する.
295 *
296 * dispatcherやcall_texrnを呼び出す場合は,Threadモードである必
297 * 要があるため,PSPスタック上にダミーの例外フレームを置いて,
298 * 擬似的に割込みハンドラからリターンする.
299 * リターンと同時にFAULTMASKが自動的にクリアされ,カーネル管理外の
300 * 割込みが許可される.
301 */
302 ldr r0, =ret_int_4 /* PC */
303 ldr r1, =EPSR_T /* xPSR(Tビットが'1'である必要がある) */
304 stmfd sp!, {r0-r1} /* ダミーフレームをスタック上に積む */
305 sub sp, #(EXC_FRAME_SIZE - (4*2)) /* r0-r3,r12,lrの内容は設定する必要がない */
306 bx r2 /* Threadモードへ移行 */
307
308ret_int_4:
309 bl search_schedtsk /* 割込み中で起動されたタスクを実行 */
310 bl run_task
311ret_int_r:
312 svc 0 /* SVCの呼び出し */
313
314/*
315 * 遅延ディスパッチからの復帰時に一時的に割込み
316 * コンテキストに移行するためのSVCコールハンドラ
317 */
318
319 .align 2
320 .thumb
321 .thumb_func
322 .globl kernel_svc_handler
323kernel_svc_handler:
324 /*
325 * 割込み処理からのリターンにより,CPUロック解除状態に移行するよ
326 * う準備する.
327 */
328 cpsid f /* 割込みロック状態へ */
329 ldr r2 , [ sp , #(EXC_FRAME_SIZE) ] /* lrをスタックから取得 */
330 add sp, #EXC_FRAME_SIZE + 8 /* スタックを捨てる */
331 mov r0, #0
332 ldr r1, =lock_flag /* CPUロック解除状態へ */
333 str r0, [r1]
334 msr basepri , r0
335 bx r2 /* リターン */
336
337/*
338 * ディスパッチャの動作開始
339 */
340 .align 2
341 .thumb
342 .thumb_func
343 .globl start_dispatch
344start_dispatch:
345 /*
346 * このルーチンは,カーネル起動時に,すべての割込みを禁止した状態
347 * (割込みロック状態と同等)で呼び出される.また,割込みモード(非
348 * タスクコンテキストと同等)で呼び出されることを想定している.
349 *
350 * prc_initializeで,lock_flagをtrueに,saved_iipmをIIPM_ENAALLに
351 * 初期化しているため,カーネル管理外の割込みを許可することで,
352 * CPUロック状態・(モデル上の)割込み優先度マスク全解除状態になる.
353 * また,task_initializeでdisdspをfalseに初期化しているため,ディ
354 * スパッチ許可状態になっている.
355 */
356 ldr r0,=istkpt /* MSPを初期化 */
357 ldr r1,[r0] /* start_dispatch呼び出し時に呼び出し用に */
358 msr msp, r1 /* 使用しているため初期化する */
359 ldr r1, =IIPM_LOCK /* カーネル管理内の割込みを禁止 */
360 msr basepri, r1
361 cpsie f /* カーネル管理外の割込みを許可 */
362 b dispatcher
363
364/*
365 * カーネルの終了処理の呼出し
366 *
367 * スタックを非タスクコンテキスト用に切り替え.
368 *
369 */
370 .text
371 .syntax unified
372 .code 16
373 .globl call_exit_kernel
374 .type call_exit_kernel, function
375call_exit_kernel:
376 b exit_kernel /* カーネルの終了処理を呼ぶ */
377
378
379/*
380 * 微少時間待ち
381 */
382 .text
383 .syntax unified
384 .code 16
385 .globl sil_dly_nse
386 .type sil_dly_nse, function
387sil_dly_nse:
388 sub r0, r0, #SIL_DLY_TIM1
389 cmp r0, #0
390 bgt sil_dly_nse1
391 mov pc, lr
392sil_dly_nse1:
393 sub r0, r0, #SIL_DLY_TIM2
394 cmp r0, #0
395 bgt sil_dly_nse1
396 mov pc, lr
Note: See TracBrowser for help on using the repository browser.