source: asp_ccsproject/trunk/asp/arch/arm_m_gcc/common/core_support.S@ 85

Last change on this file since 85 was 85, checked in by ecsg-okazaki, 10 years ago

2014/09/26 ECS E.Okazaki Folder configuration change

File size: 31.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) 2008-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 *
9 * 上記著作権者
10は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再é…
13å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再é…
19å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
20å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
21 * 者
22マニュアルなど)に,上記の著作権表示,この利用条件および下記
23 * の無保証規定を掲載すること.
24 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
25 * 用できない形で再é…
26å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
27 * と.
28 * (a) 再é…
29å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
30マニュアルなど)に,上記の著
31 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
32 * (b) 再é…
33å¸ƒã®å½¢æ…
34‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
35 * 報告すること.
36 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
37 * 害からも,上記著作権者
38およびTOPPERSプロジェクトをå…
39è²¬ã™ã‚‹ã“と.
40 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
41 * 由に基づく請求からも,上記著作権者
42およびTOPPERSプロジェクトを
43 * å…
44è²¬ã™ã‚‹ã“と.
45 *
46 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
47お
48 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
49 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
50 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
51 * の責任を負わない.
52 *
53 * @(#) $Id: core_support.S 2316 2012-02-23 06:30:11Z ertl-honda $
54 */
55
56/*
57 * プロセッサ依存モジュール アセンブリ言語部(ARM-M用)
58 */
59
60#define TOPPERS_MACRO_ONLY
61#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
62#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
63#define CAST(type, val) (val) /* 型キャストを行うマクロ */
64
65#include "kernel_impl.h"
66#include "arm_m.h"
67#include "offset.h"
68#include "target_asm.inc"
69
70/*
71 * CCS向け属性設定
72 */
73 .cpu cortex-m4
74 .eabi_attribute Tag_ABI_HardFP_use,3
75 .eabi_attribute Tag_ABI_VFP_args,1
76 .fpu fpv4-sp-d16
77 .eabi_attribute Tag_ABI_FP_denormal,1
78 .eabi_attribute Tag_ABI_FP_exceptions,1
79 .eabi_attribute Tag_ABI_FP_number_model,3
80 .eabi_attribute Tag_ABI_align8_needed,1
81 .eabi_attribute Tag_ABI_align8_preserved,1
82 .eabi_attribute Tag_ABI_enum_size,1
83 .eabi_attribute Tag_ABI_optimization_goals,2
84 .eabi_attribute Tag_ABI_PCS_wchar_t,2
85 .eabi_attribute Tag_CPU_unaligned_access,1
86
87/*
88 * タスクディスパッチャ
89 */
90 ATEXT
91 AALIGN(2)
92 ATHUMB(dispatch)
93 AGLOBAL(dispatch)
94ALABEL(dispatch)
95 /*
96 *
97 * このルーチンは,タスクコンテキスト・CPUロック状æ…
98‹ãƒ»ãƒ‡ã‚£ãƒ‘ッチ許可状æ…
99‹
100 * ・(モデル上の)割込み優å…
101ˆåº¦ãƒžã‚¹ã‚¯å…
102¨é–‹çŠ¶æ…
103‹ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Ž
104 */
105 stmfd sp!,{r4-r11,lr} /* レジスタの保存 */
106 ldr r0, =p_runtsk /* p_runtskを読み込む */
107 ldr r1, [r0]
108 str sp, [r1,#TCB_sp] /* タスクスタックを保存 */
109 ldr lr, =dispatch_r /* 実行再開番地を保存 */
110 str lr, [r1,#TCB_pc]
111 b dispatcher
112
113 ATHUMB(dispatch_r)
114 AGLOBAL(dispatch_r)
115ALABEL(dispatch_r)
116 ldmfd sp!,{r4 - r11,lr} /* レジスタの復帰 */
117 /*
118 * タスク例外処理ルーチンの起動
119 * dispatcherから呼び出されるため,TCBのアドレスはr1にå…
120¥ã£ã¦ã„ã‚‹
121 */
122 ldrb r0,[r1,#TCB_enatex]
123 tst r0,#TCB_enatex_mask
124 beq dispatch_r_1 /* enatex が false ならリターン */
125 ldr r0,[r1,#TCB_texptn] /* texptn が 0 ならリターン */
126 tst r0,r0
127 beq dispatch_r_1
128 ldr r1, =ipmflg /* ipmflgが false ならリターン */
129 ldr r0, [r1]
130 tst r0,r0
131 beq dispatch_r_1
132 ldr r0, =call_texrtn /* タスク例外ルーチンの呼び出し */
133 bx r0
134ALABEL(dispatch_r_1) /* タスクへのcall_textnから戻る */
135 bx lr
136
137
138/*
139 * CPU例外エントリ
140 *
141 * 割込みエントリと処理の内
142容は同等だが,ログの種類が異なるため,
143 * 分けている.
144 */
145 AALIGN(2)
146 ATEXT
147 ATHUMB(core_exc_entry)
148 AGLOBAL(core_exc_entry)
149ALABEL(core_exc_entry)
150 /*
151 * 例外/割込みが発生すると,発生時にアクティブなスタックにスクラ
152 * ッチレジスタ等が保存される.
153 * この内
154容に加えて,CPU例外ハンドラへの情
155報として,basepri の値と,
156 * EXC_RETURNの情
157報を加えて保存する.basepriの値は,CPU例外からの
158 * リターン時に割込み優å…
159ˆåº¦ãƒžã‚¹ã‚¯ã®å€¤ã‚’å…
160ƒã«æˆ»ã™ãŸã‚ã«ã‚‚用いられる.
161 *
162 * -----------
163 * | EXC_RETURN|
164 * -----------
165 * | basepri |
166 * -----------
167 * | R0 |
168 * -----------
169 * | R1 |
170 * -----------
171 * | R2 |
172 * -----------
173 * | R3 |
174 * -----------
175 * | R12 |
176 * -----------
177 * | LR |
178 * -----------
179 * | PC |
180 * -----------
181 * | xPSR |
182 * -----------
183 *
184 */
185
186 /*
187 * カーネル管理外の例外かチェック
188 * カーネル内
189のクリティカルセクションの実行中,å…
190¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
191‹ï¼Œ
192 * CPUロック状æ…
193‹ï¼Œã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–の割込みハンドラ実行中のいずれかで
194 * 発生したCPU例外を,カーネル管理外のCPU例外と呼ぶ
195 * å…
196¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
197‹ã¯FAULTMASKが'1'の場合
198 * CPUロック状æ…
199‹ã¯basepriがIIPM_LOCKかで判断する.
200 */
201 mrs r2, FAULTMASK /* å…
202¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
203‹ãªã‚‰ã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–例外処理へ */
204 cbnz r2, core_nonkernel_exc_entry
205
206 mrs r2, basepri /* baepriの値を取得 */
207 cmp r2, #IIPM_LOCK /* CPUロック状æ…
208‹ãªã‚‰ã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–例外処理へ */
209 beq core_nonkernel_exc_entry
210
211
212 /*
213 * スタックを変更する必
214要があるかチェック
215 * EXC_RETURN(割込み時にLRに設定される値)をチェックして,例外発生時に
216 * アクティブなスタックを特定することで多重割込みか判定する.
217 */
218 tst lr, #EXC_RETURN_PSP /* 割込みå…
219ƒãŒMSPなら多重割込み */
220 beq core_exc_entry_1 /* 多重割込みならcore_exc_entry_1へ */
221 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
222 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
223ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
224 stmfd r0!,{lr} /* EXC_RETURN を積む */
225 msr psp, r0 /* CPU例外ハンドラへの引数となる */
226 push {lr} /* MSP上にもEXC_RETURN を積む */
227 b core_exc_entry_2
228ALABEL(core_exc_entry_1) /* 多重割込みの場合 */
229 push {r2} /* 割込み発生時の割込み優å…
230ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
231 push {lr} /* EXC_RETURN を積む */
232 mov r0, sp /* CPU例外ハンドラへの引数となる */
233
234 /*
235 * å…
236±é€šå‡¦ç†
237 */
238ALABEL(core_exc_entry_2)
239 mrs r3, ipsr /* ハンドラアドレスを取得 */
240 ldr r1, =_kernel_exc_tbl
241 ldr r2, [r1, r3, lsl #2]
242
243#ifdef LOG_EXC_ENTER
244 push {r0,r2,r3}
245 mov r0, r3 /* 例外番号をパラメータに */
246 bl log_exc_enter /* log_exc_enterを呼び出す */
247 pop {r0,r2,r3}
248 push {r3} /* 例外番号をスタックへ */
249#endif /* LOG_EXC_ENTER */
250
251 /*
252 * CPU例外ハンドラの呼び出し
253 */
254 blx r2
255
256#ifdef LOG_EXC_ENTER
257 pop {r0} /* 例外番号を引数に */
258 bl log_exc_leave /* log_exc_leaveを呼び出す */
259#endif /* LOG_EXC_ENTER */
260
261 b ret_exc
262
263/*
264 * カーネル管理外のCPU例外の出å…
265¥å£å‡¦ç†
266 */
267ALABEL(core_nonkernel_exc_entry)
268 tst lr, #EXC_RETURN_PSP /* 割込みå…
269ƒãŒMSPなら多重割込み */
270 beq core_nonkernel_exc_entry_1 /* 多重割込みなら */
271 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
272 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
273ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
274 stmfd r0!,{lr} /* EXC_RETURN を積む */
275 msr psp, r0 /* CPU例外ハンドラへの引数となる */
276 push {lr} /* MSP上にもEXC_RETURN を積む */
277 b core_nonkernel_exc_entry_2
278ALABEL(core_nonkernel_exc_entry_1) /* 多重割込みの場合 */
279 push {r2} /* 割込み発生時の割込み優å…
280ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
281 push {lr} /* EXC_RETURN を積む */
282 mov r0, sp /* CPU例外ハンドラへの引数となる */
283
284ALABEL(core_nonkernel_exc_entry_2)
285 mrs r3, ipsr /* CPU例外ハンドラのアドレスを取得 */
286 ldr r1, =_kernel_exc_tbl
287 ldr r2, [r1, r3, lsl #2]
288
289 /*
290 * CPU例外ハンドラの呼び出し
291 */
292 blx r2
293
294 /*
295 * 割込みロック状æ…
296‹ã¨ã™ã‚‹ï¼Ž
297 */
298 cpsid f
299
300 /*
301 * 戻りå…
302ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®åˆ¤å®š
303 *
304 * 割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして,戻り
305 * å…
306ˆã§MSPが使われていれば,割込みå…
307ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã¨åˆ¤å®šã™ã‚‹ï¼Ž
308 */
309 pop {r3} /* lrをスタックから取得 */
310 tst r3, #EXC_RETURN_PSP /* 戻りå…
311ˆãŒPSPなら */
312 bne core_nonkernel_ret_exc_1
313 pop {r1} /* å…
314ƒã®å‰²è¾¼ã¿å„ªå…
315ˆåº¦ãƒžã‚¹ã‚¯(basepri) */
316 b core_nonkernel_ret_exc_2 /* の値をMSPから取得 */
317
318ALABEL(core_nonkernel_ret_exc_1)
319 /*
320 * PSP上からEXC_RETURNを削除
321 */
322 mrs r2, psp
323 add r2, r2, #4
324 /*
325 * å…
326ƒã®å‰²è¾¼ã¿å„ªå…
327ˆåº¦ãƒžã‚¹ã‚¯(basepri)の値をPSPから取得
328 */
329 ldmfd r2!, {r1}
330 msr psp, r2
331
332ALABEL(core_nonkernel_ret_exc_2)
333 msr basepri, r1 /* 割込み優å…
334ˆåº¦ãƒžã‚¹ã‚¯ã‚’割込み前に状æ…
335‹ã¸ */
336 bx r3 /* リターン */
337
338/*
339 * 割込みエントリ
340 */
341 ATHUMB(core_int_entry)
342 AGLOBAL(core_int_entry)
343ALABEL(core_int_entry)
344 /*
345 * 割込み発生時の割込み優å…
346ˆåº¦ãƒžã‚¹ã‚¯ã‚’スタックに保存するため取得
347 */
348 mrs r2, basepri /* baepriの値を取得 */
349
350 /*
351 * 多重割込みかチェック
352 * EXC_RETURN(割込み時にLRに設定される値)をチェックして,例外発生時に
353 * アクティブなスタックを特定することで多重割込みか判定する.
354 */
355 tst lr, #EXC_RETURN_PSP /* 割込みå…
356ƒãŒMSPなら多重割込み */
357 beq core_int_entry_1 /* 多重割込みならcore_int_entry_1へ */
358 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
359 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
360ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
361 stmfd r0!,{lr} /* EXC_RETURN を積む */
362 msr psp, r0 /* CPU例外ハンドラへの引数となる */
363 push {lr} /* MSP上にもEXC_RETURN を積む */
364 b core_int_entry_2
365ALABEL(core_int_entry_1) /* 多重割込みの場合 */
366 push {r2} /* 割込み発生時の割込み優å…
367ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
368 push {lr} /* EXC_RETURN を積む */
369 mov r0, sp /* 未定義の割込みが発生した場合の情
370報とする */
371
372 /*
373 * å…
374±é€šå‡¦ç†
375 */
376ALABEL(core_int_entry_2)
377 mrs r3, ipsr /* ハンドラアドレスを取得 */
378 ldr r1, =_kernel_exc_tbl
379 ldr r2, [r1, r3, lsl #2]
380
381 /*
382 * basepriの設定
383 * NVIC優å…
384ˆåº¦ãƒžã‚¹ã‚¯ãŒè‡ªå‹•çš„に設定されるため優å…
385ˆåº¦ãƒžã‚¹ã‚¯ã®ç‚¹ã§ã¯å¿…
386要な
387 * いが,x_get_ipm()がbasepriを参ç…
388§ã™ã‚‹ãŸã‚ï¼Œbasepriも更新する.
389 */
390 ldr r1, =_kernel_int_iipm_tbl
391 ldr lr, [r1, r3, lsl #2]
392 msr basepri, lr
393
394#ifdef LOG_INH_ENTER
395 push {r0,r2,r3}
396 mov r0, r3 /* 例外番号をパラメータに */
397 bl log_inh_enter /* log_exc_enterを呼び出す */
398 pop {r0,r2,r3}
399 push {r3} /* 例外番号をスタックへ */
400#endif /* LOG_EXC_ENTER */
401
402 /*
403 * 割込みハンドラの呼び出し
404 */
405 blx r2
406
407#ifdef LOG_INH_LEAVE
408 pop {r0} /* 例外番号を引数に */
409 bl log_exc_leave /* log_exc_leaveを呼び出す */
410#endif /* LOG_INH_LEAVE */
411
412
413
414/*
415 * 割込み/例外出口
416 *
417 * ret_exc/ret_intは,CPU例外/割込みハンドラから戻った直後に実行する
418 * ルーチンである.
419 */
420ALABEL(ret_exc)
421ALABEL(ret_int)
422 /*
423 * 割込みロック状æ…
424‹ã¨ã™ã‚‹ï¼Žã“の時点では,CPUロック状æ…
425‹ã«ã¯ãªã‚‰ãªã„
426 * (basepriとlock_flagとsaved_iipmは更新しない).
427 *
428 * 割込みロック状æ…
429‹ã¨ã™ã‚‹ã®ã¯ï¼Œæˆ»ã‚Šå…
430ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®ãƒã‚§ãƒƒã‚¯ã¨ï¼Œ
431 * 戻りå…
432ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§ã‚った場合のリターンをアトミック
433 * に行うためである.bsepriをCPUロックの値にすることでもアトミッ
434 * クなチェックと復帰は可能であるが,割込みからリターンしても,
435 * basepri の設定内
436容はå…
437ƒã«æˆ»ã‚‰ãªã„ため,使用することができない.
438 * 一方,FAULTMASKは,割込みからのリターン処理によって,'0'にクリ
439 * アされる.
440 */
441 cpsid f
442
443 /*
444 * 戻りå…
445ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®åˆ¤å®š
446 *
447 * 割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして,戻り
448 * å…
449ˆã§MSPが使われていれば,割込みå…
450ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã¨åˆ¤å®šã™ã‚‹ï¼Ž
451 */
452 pop {r3} /* lrをスタックから取得 */
453 tst r3, #EXC_RETURN_PSP /* 戻りå…
454ˆãŒPSPなら ret_int_1 へ */
455 bne ret_int_1
456 pop {r1} /* å…
457ƒã®å‰²è¾¼ã¿å„ªå…
458ˆåº¦ãƒžã‚¹ã‚¯(basepri)をr1へ */
459 b ret_int_2 /* の値をMSPから取得 */
460
461 /*
462 * 一段目の割込みの出口処理
463 */
464ALABEL(ret_int_1)
465 /*
466 * PSP上から,EXC_RETURN(r0)とå…
467ƒã®å‰²è¾¼ã¿å„ªå…
468ˆåº¦ãƒžã‚¹ã‚¯(basepri)(r1)
469 * を取得
470 */
471 mrs r2, psp
472 ldmfd r2!, {r0,r1}
473 msr psp, r2
474
475 /*
476 * reqflgをチェックする
477 *
478 * カーネル管理内
479の割込みは禁止した状æ…
480‹ã§å®Ÿè¡Œã™ã‚‹å¿…
481要があるため,
482 * FAULTMASKを'1'にした状æ…
483‹ã§å®Ÿè¡Œã™ã‚‹ï¼Ž
484 * reqflgをチェックする前に割込みを禁止するのは,reqflgをチェック
485 * した直後に割込みハンドラが起動され,その中でディスパッチが要求
486 * された場合に,すぐにディスパッチされないという問題が生じるため
487 * である.
488 */
489 ldr r0, =reqflg /* reqflgがfalseならそのまま戻る */
490 ldr r2, [r0]
491 cbnz r2, ret_int_3 /* trueならret_int_3へ */
492
493ALABEL(ret_int_2)
494 /*
495 * ここには割込みロック状æ…
496‹ï¼ˆFAULTMASKがセット)された状æ…
497‹ã§æ¥ã‚‹ï¼Ž
498 * Threadモードからのリターンにより自動的に割込みロック解除状æ…
499‹ã«ãªã‚‹ï¼Ž
500 * 割込み優å…
501ˆåº¦ãƒžã‚¹ã‚¯ã¯å‰²è¾¼ã¿å‰ã«çŠ¶æ…
502‹ã«æˆ»ã™ï¼Ž
503 */
504 msr basepri, r1 /* 割込み優å…
505ˆåº¦ãƒžã‚¹ã‚¯ã‚’割込み前に状æ…
506‹ã¸ */
507 bx r3 /* リターン */
508
509ALABEL(ret_int_3)
510 /*
511 * ここでは,戻りå…
512ˆãŒã‚¿ã‚¹ã‚¯ã§ã‚り,PSP上にスクラッチレジスタと割
513 * 込み優å…
514ˆåº¦ãƒžã‚¹ã‚¯(basepri)が保存された状æ…
515‹ã«ãªã£ã¦ã„る.また,
516 * プロセッサは,Handlerモード・割込みロック状æ…
517‹ã¨ãªã£ã¦ã„る.
518 * また,r0には,reqflgのアドレス,r3には割込み受付時のlrの値が保
519 * 持されている.
520 */
521 /*
522 * タスク例外ハンドラやディスパッチをする際にThreadモードへ遷移する
523 * ダミーのスタックフレームを作成して,bx命令でHandlerモードからリ
524 * ターンする.また,遅
525延ディスパッチする場合も,再び割り込んだタス
526 * クに戻る際には,svc命令で,svc_handlerを呼び出す.
527 * スタックフレームは,Configureation and Control Register(CCR)の
528 * STKALIGNが'1'の場合は,8byte境界にアラインされる.
529 * 参考 : DDI0403B_arm_architecture_v7m_reference_manual(P.220)
530 * そのため,この時点のスタックは割込みや例外発生時に作成された
531 * スタックフレームから,8byte境界のサイズにしておくと,svc_handler
532 * 等でスタックフレームのアライメントの有無の確認を省略できる.
533 * ただし,システム起動後は,動的にCCRのSTKALIGNの設定を変更するのは
534 * 禁止とする.
535 * この時点は標準のスタックフレームは,割込み・例外発生時と同等であ
536 * るため,タスクスタック(PSP)は8byte境界になっている.
537 */
538 mov r1, #0 /* reqflgをfalseに */
539 str r1, [r0]
540
541 /*
542 * CPUロック状æ…
543‹ã«ç§»è¡Œã™ã‚‹ï¼Ž
544 *
545 * カーネルの管理内
546の割込みを禁止するようにbasepriを設定し,
547 * lock_flag と saved_iipm を更新する.saved_iipmは,戻りå…
548ˆã®å‰²è¾¼ã¿
549 * 優å…
550ˆåº¦ãƒžã‚¹ã‚¯ï¼ˆã®å†…
551部表現)に設定する.
552 * この時点でCPUロック状æ…
553‹ã¨ã™ã‚‹ã®ã¯ï¼Œdispatcherへ分岐する時と,
554 * call_texrtnを呼び出す時に,CPUロック状æ…
555‹ã«ãªã£ã¦ã„ã‚‹å¿…
556要がある
557 * ためである.
558 * なお,この処理の後,Threadモードへの移行処理を行なうため,割込み
559 * ロック状æ…
560‹(FAULTMASKを"1")は保持する.
561 */
562 ldr r1, =IIPM_LOCK /* CPUロック状æ…
563‹ */
564 msr basepri, r1
565 mov r1, #0x01 /* lock_flag を trueに */
566 ldr r0, =lock_flag
567 str r1, [r0]
568
569 /*
570 * 割込み優å…
571ˆåº¦ãƒžã‚¹ã‚¯ã‚’,å…
572¨è§£é™¤çŠ¶æ…
573‹ï¼ˆTIPM_ENAALL)に設定する
574 * すでにCPUロック状æ…
575‹ãªã®ã§ï¼Œsaved_iipmをIIPM_ENAALLとする.
576 */
577 ldr r1, =IIPM_ENAALL
578 ldr r0, =saved_iipm
579 str r1, [r0]
580
581 /*
582 * Threadモードへ移行する.
583 *
584 * dispatcherやcall_texrnを呼び出す場合は,Threadモードである必
585
586 * 要があるため,PSPスタック上にダミーの例外フレームを置いて,
587 * 擬似的に割込みハンドラからリターンする.
588 * リターンと同時にFAULTMASKが自動的にクリアされ,カーネル管理外の
589 * 割込みが許可される.
590 */
591 ldr r0, =ret_int_4 /* PC */
592 ldr r1, =EPSR_T /* xPSR(Tビットが'1'である必
593要がある) */
594 mrs r2, psp
595 stmfd r2!, {r0-r1} /* ダミーフレームをスタック上に積む */
596 sub r2, #(EXC_FRAME_SIZE - (4*2)) /* r0-r3,r12,lrの内
597容は設定する必
598要がない */
599 msr psp,r2
600 bx r3 /* Threadモードへ移行 */
601
602ALABEL(ret_int_4)
603 /*
604 * 上記の処理により,Threadモードで実行される.
605 * dspflgがfalseである場合と,p_runtskとp_schedtskが同じ場合には,
606 * ディスパッチを行わない.このチェックが必
607要なのは,タスク例外処
608 * 理ルーチンの呼出しが必
609要な場合に,ディスパッチが必
610要なくても,
611 * reqflgをtrueにするためである.
612 */
613 ldr r0, =p_runtsk /* ディスパッチを行わない場合でも,r1にp_runtsk の値(TCB) */
614 ldr r1, [r0] /* がå…
615¥ã£ã¦ã„ã‚‹å¿…
616要があるので,å…
617ˆã«èª­ã¿è¾¼ã‚€ */
618 ldr r0, =dspflg
619 ldr r2, [r0]
620 cbz r2, ret_int_r_1 /* dspflgがfalseならret_int_r_1へ */
621 ldr r0, =p_schedtsk
622 ldr r2, [r0]
623 cmp r1, r2 /* p_runtskとp_schedtskが同じなら */
624 beq ret_int_r_1 /* ret_int_r_1へ */
625 stmfd sp!, {r4-r11} /* 残りのレジスタを保存 */
626 str sp, [r1,#TCB_sp] /* タスクスタックを保存 */
627 ldr lr, =ret_int_r /* 実行再開番地を保存 */
628 str lr, [r1,#TCB_pc]
629 b dispatcher /* ディスパッチャへ */
630
631/*
632 * 割込みによりプリエンプトされたタスクへのリターン処理
633 *
634 * Threadモードで,ディスパッチャや割込みの出口処理から呼び出される.
635 * 割込みによりプリエンプトされたタスクへリターンするには,いったん
636 * Handlerモードに移行し,PCに0xfffffffdを代å…
637¥ã—てリターンする必
638要
639 * がある.そのため,SVCにより,SVCハンドラを呼び出し,Handlerモー
640 * ドへ移行する.
641 */
642 ATHUMB(ret_int_r)
643 AGLOBAL(ret_int_r)
644ALABEL(ret_int_r)
645 pop {r4-r11} /* レジスタの復帰 */
646ALABEL(ret_int_r_1)
647 /*
648 * enatexがtrueで,texptnが0でなければ,タスク例外処理ルーチンを
649 * 呼び出す.
650 * dispatcherから呼び出されるため,TCBのアドレスはr1にå…
651¥ã£ã¦ã„ã‚‹
652 */
653 ldrb r0, [r1,#TCB_enatex]
654 tst r0, #TCB_enatex_mask
655 beq ret_int_r_2 /* enatex が false なら ret_int_r_2へ */
656 ldr r0, [r1,#TCB_texptn] /* texptn が 0 ならリターン */
657 cbz r0, ret_int_r_2
658 ldr r1, =ipmflg /* ipmflgが false ならリターン */
659 ldr r0, [r1]
660 cbz r0, ret_int_r_2
661 bl call_texrtn /* タスク例外ルーチンの呼び出し */
662ALABEL(ret_int_r_2)
663 svc 0 /* SVCの呼び出し */
664
665/*
666 * SVCハンドラ
667 */
668 ATHUMB(svc_handler)
669 AGLOBAL(svc_handler)
670ALABEL(svc_handler)
671 /*
672 * 割込み処理からのリターンにより,CPUロック解除状æ…
673‹ã«ç§»è¡Œã™ã‚‹ã‚ˆ
674 * う準備する.
675 */
676 cpsid f /* 割込みロック状æ…
677‹ã¸ */
678 mrs r0, psp
679 add r0, #EXC_FRAME_SIZE /* スタックを捨てる */
680 msr psp, r0
681 mov r0, #0
682 ldr r1, =lock_flag /* CPUロック解除状æ…
683‹ã¸ */
684 str r0, [r1]
685 ldr r1, =IIPM_ENAALL /* 割込み優å…
686ˆåº¦ãƒžã‚¹ã‚¯ã‚’å…
687¨è§£é™¤çŠ¶æ…
688‹ã«è¨­å®š */
689 msr basepri, r1
690 bx lr /* リターン */
691
692/*
693 * ディスパッチャの動作開始
694 */
695 ATHUMB(start_dispatch)
696 AGLOBAL(start_dispatch)
697ALABEL(start_dispatch)
698 /*
699 * このルーチンは,カーネル起動時に,すべての割込みを禁止した状æ…
700‹
701 * (割込みロック状æ…
702‹ã¨åŒç­‰ï¼‰ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Žã¾ãŸï¼Œå‰²è¾¼ã¿ãƒ¢ãƒ¼ãƒ‰ï¼ˆéž
703 * タスクコンテキストと同等)で呼び出されることを想定している.
704 *
705 * core_initializeで,lock_flagをtrueに,saved_iipmをIIPM_ENAALLに
706 * 初期化しているため,カーネル管理外の割込みを許可することで,
707 * CPUロック状æ…
708‹ãƒ»ï¼ˆãƒ¢ãƒ‡ãƒ«ä¸Šã®ï¼‰å‰²è¾¼ã¿å„ªå…
709ˆåº¦ãƒžã‚¹ã‚¯å…
710¨è§£é™¤çŠ¶æ…
711‹ã«ãªã‚‹ï¼Ž
712 * また,task_initializeでdisdspをfalseに初期化しているため,ディ
713 * スパッチ許可状æ…
714‹ã«ãªã£ã¦ã„る.
715 */
716 ldr r0,=istkpt /* MSPを初期化 */
717 ldr r1,[r0] /* start_dispatch呼び出し時に呼び出し用に */
718 msr msp, r1 /* 使用しているため初期化する */
719 ldr r1, =IIPM_LOCK /* カーネル管理内
720の割込みを禁止 */
721 msr basepri, r1
722 cpsie f /* カーネル管理外の割込みを許可 */
723#ifdef LOG_DSP_ENTER
724 ldr r1, =p_runtsk /* p_runtskをパラメータに */
725 ldr r0, [r1]
726 bl log_dsp_enter
727#endif /* LOG_DSP_ENTER */
728 mov r0, #CONTROL_PSP /* PSPを有効に */
729 msr control, r0
730 isb /* control の操作後に必
731要 */
732
733/*
734 * 現在のコンテキストを捨ててディスパッチ
735 */
736 ATHUMB(exit_and_dispatch)
737 AGLOBAL(exit_and_dispatch)
738ALABEL(exit_and_dispatch)
739 /* ディスパッチャ本体(dispatcher)へ */
740
741
742/*
743 * ディスパッチャ本体
744 */
745ALABEL(dispatcher)
746 /*
747 * このルーチンは,タスクコンテキスト・CPUロック状æ…
748‹ãƒ»ãƒ‡ã‚£ã‚¹ãƒ‘ッチ
749 * 許可状æ…
750‹ãƒ»ï¼ˆãƒ¢ãƒ‡ãƒ«ä¸Šã®ï¼‰å‰²è¾¼ã¿å„ªå…
751ˆåº¦ãƒžã‚¹ã‚¯å…
752¨è§£é™¤çŠ¶æ…
753‹ã§å‘¼ã³å‡ºã•
754 * れる.
755 *
756 * すなわち,Threadモード・lock_flagがtrue・disdspがfalse・dspflg
757 * がtrue・saved_iipmがIIPM_ENAALLとなっている.実行再開番地へもこ
758 * の状æ…
759‹ã®ã¾ã¾åˆ†å²ã™ã‚‹ï¼Ž
760 */
761ALABEL(dispatcher_0)
762 ldr r0, =p_schedtsk /* p_schedtskをp_runtskに */
763 ldr r1, [r0]
764 ldr r2, =p_runtsk
765 str r1, [r2]
766 cbz r1, dispatcher_1 /* p_runtskがNULLならdispatcher_1へ */
767 ldr sp, [r1,#TCB_sp] /* タスクスタックを復帰 */
768#ifdef LOG_DSP_LEAVE
769 mov r0, r1 /* p_runtskをパラメータに */
770 mov r4, r1 /* r1はスクラッチレジスタなので保存 */
771 bl log_dsp_leave
772 mov r1, r4
773#endif /* LOG_DSP_LEAVE */
774 ldr pc, [r1,#TCB_pc] /* 実行再開番地を復帰 */
775ALABEL(dispatcher_1)
776 /*
777 * CPUロック状æ…
778‹ã®è§£é™¤ã¨ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå®Ÿè¡ŒçŠ¶æ…
779‹ã¸ã®
780 * 準備をする
781 */
782 mov r0, #CONTROL_MSP /* MSPを有効に */
783 msr control, r0
784 isb /* control の操作後に必
785要 */
786 mov r4, #0 /* r4 <- '0' */
787 ldr r5, =IIPM_LOCK /* r5 <- 割込みロック状æ…
788‹ã®å‰²è¾¼ã¿å„ªå…
789ˆåº¦ãƒžã‚¹ã‚¯ã®å€¤ */
790 ldr r6, =reqflg /* r6 <- reqflg */
791 ldr r7, =lock_flag /* r7 <- lock_flg */
792 str r4, [r7] /* CPUロック解除状æ…
793‹ã¸ */
794ALABEL(dispatcher_2)
795 /*
796 * 割込みを許可し,非タスクコンテキスト実行状æ…
797‹ã¨ã—割込みを待
798つ.
799 *
800 * ここで非タスクコンテキスト実行状æ…
801‹ã«åˆ‡ã‚Šæ›ãˆã‚‹ã®ã¯ï¼Œã“こで発生
802 * する割込み処理にどのスタックを使うかという問題の解決と,割込み
803 * ハンドラ内
804でのタスクディスパッチの防止という2つの意味がある.
805 *
806 * プロセッサを割込み待
807ちに移行させる処理と,割込み許可とは,不可
808 * 分に行なう必
809要がある.
810 * これを不可分に行なわない場合,割込みを許可した直後に割込
811 * みがå…
812¥ã‚Šï¼Œãã®ä¸­ã§ã‚¿ã‚¹ã‚¯ãŒå®Ÿè¡Œå¯èƒ½çŠ¶æ…
813‹ã«ãªã‚‹ã¨ï¼Œå®Ÿè¡Œã™ã¹ãã‚¿ã‚¹
814 * クがあるにもかかわらずプロセッサが割込み待
815ちになってしまう.
816 * ARM-Mでは,PRIMASKをセットした状æ…
817‹ã§WFIを呼び出すことで実現できる.
818 * この状æ…
819‹ã§å‰²è¾¼ã¿ãŒå…
820¥ã‚‹ã¨ï¼Œå‰²è¾¼ã¿ã¯å®Ÿè¡Œã•ã‚Œãšï¼ŒWFIからリターンす
821 * ることになるので,一旦割込みを許可して割込みハンドラを実行する.
822 *
823 * 割込み待
824ちの間は,p_runtskをNULL(=0)に設定しなければならな
825 * い.このように設定しないと,割込みハンドラからiget_tidを呼び出
826 * した際の動作が仕様に合致しなくなる.
827 *
828 * ターゲットによっては,省電力モード等に移行するため,標準の方法と
829 * 異なる手順が必
830要な場合がある.
831 * そのようなターゲットでは,ターゲット依存において,TOPPERS_CUSTOM_IDLE
832 * を定義し,アセンブラマクロとして,toppers_asm_custom_idle を用意
833 * すればよい.
834 *
835 * なお,toppers_asm_custom_idle の記述にあたっては,次のレジスタは
836 * toppers_asm_custom_idleの前後で使用するため,
837 * toppers_asm_custom_idle 内
838で使用する場合は,前後で保存復帰すること.
839 * これらのレジスタは Calee saved レジスタであるため,
840 * toppers_asm_custom_idle として関数呼び出しをした場合は,呼び出した
841 * 関数で自動的に保存復帰されるため,アセンブラレベルでの保存復帰は必
842
843 * 要ない.
844 *
845 * レジスタ : 内
846容
847 * r4 : '0'
848 * r5 : 'IIPM_LOCK'
849 * r6 : reqflgのアドレス
850 * r7 : lock_flgのアドレス
851 * sp : 非タスクコンテキスト用のスタックのå…
852ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹(msp)
853 */
854#ifdef TOPPERS_CUSTOM_IDLE
855 toppers_asm_custom_idle
856#else
857 cpsid i /* PRIMASK をセット */
858 msr basepri, r4 /* å…
859¨å‰²è¾¼ã¿è¨±å¯ */
860 wfi
861 cpsie i /* PRIMASK をクリア(割込みを受け付ける) */
862 msr basepri, r5 /* CPUロック状æ…
863‹ã¸ */
864#endif /* TOPPERS_CUSTOM_IDLE */
865
866 ldr r0, [r6] /* reqflgがfalseならdispatcher_2へ */
867 cmp r0, #0
868 beq dispatcher_2
869 str r4, [r6] /* reqflgをfalseに */
870
871 /*
872 * CPUロック状æ…
873‹ã«æˆ»ã™ï¼Žå‰²è¾¼ã¿å¾…
874ちの間に実行した割込みハンドラによ
875 * り,saved_iipmが書き換えられる可能性があるため,å…
876ƒã®å€¤ã«æˆ»ã™å¿…
877
878 * 要がある.dispatcherが実行される時は,saved_iipmがIIPM_ENAALL
879 * となっているため,ここではsaved_iipmをIIPM_ENAALL(=0)に戻せ
880 * ばよい.
881 */
882 mov r0, #CONTROL_PSP /* PSPを有効に */
883 msr control, r0
884 isb /* control の操作後に必
885要 */
886 mov r2, #1 /* lock_flagをtrueへ */
887 str r2, [r7]
888 ldr r0, =saved_iipm /* saved_iipm を0に */
889 str r4, [r0]
890 b dispatcher_0
891
892
893/*
894 * カーネルの終了処理の呼出し
895 *
896 * スタックを非タスクコンテキスト用に切り替え.
897 *
898 */
899 ATHUMB(call_exit_kernel)
900 AGLOBAL(call_exit_kernel)
901ALABEL(call_exit_kernel)
902 mov r0, #CONTROL_MSP
903 msr control, r0 /* MSPを有効に */
904 isb /* control の操作後に必
905要 */
906 ldr r0, =exit_kernel /* カーネルの終了処理を呼ぶ */
907 bx r0
908
909
910/*
911 * タスク起動処理
912 *
913 * dispatcherから呼び出されるため,TCBのアドレスはr1にå…
914¥ã£ã¦ã„ã‚‹
915 *
916 */
917 ATHUMB(start_r)
918 AGLOBAL(start_r)
919ALABEL(start_r)
920 mov r0, #0
921 ldr r4, =lock_flag /* CPUロック解除状æ…
922‹ã¸ */
923 str r0, [r4]
924 msr basepri, r0 /* 割込み許可 */
925 ldr lr, =ext_tsk /* 戻り番地設定 */
926 ldr r2, [r1, #TCB_p_tinib] /* p_runtsk->p_tinibをr2に */
927 ldr r0, [r2, #TINIB_exinf] /* exinfを引数レジスタr0に */
928 ldr r1, [r2, #TINIB_task] /* タスク起動番地にジャンプ */
929 bx r1
930
931/*
932 * 微少時間待
933ち
934 */
935 AALIGN(2)
936 ATEXT
937 ATHUMB(sil_dly_nse)
938 AGLOBAL(sil_dly_nse)
939ALABEL(sil_dly_nse)
940 sub r0, r0, #SIL_DLY_TIM1
941 cmp r0, #0
942 bgt sil_dly_nse1
943 bx lr
944ALABEL(sil_dly_nse1)
945 sub r0, r0, #SIL_DLY_TIM2
946 cmp r0, #0
947 bgt sil_dly_nse1
948 bx lr
Note: See TracBrowser for help on using the repository browser.