source: asp3_wo_tecs/trunk/arch/arm_m_gcc/common/core_support.S@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

File size: 25.4 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) 2005-2015 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * @(#) $Id: core_support.S 323 2015-05-28 08:48:22Z ertl-ishikawa $
56 */
57
58/*
59 * プロセッサ依存モジュール アセンブリ言語部(ARM-M用)
60 */
61
62#define TOPPERS_MACRO_ONLY
63#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
64#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
65#define CAST(type, val) (val) /* 型キャストを行うマクロ */
66
67#include "kernel_impl.h"
68#include "arm_m.h"
69#include "offset.h"
70#include "target_asm.inc"
71
72/*
73 * タスクディスパッチャ
74 */
75 ATEXT
76 AALIGN(2)
77 ATHUMB(_dispatch)
78 AGLOBAL(_dispatch)
79ALABEL(_dispatch)
80#ifdef TOPPERS_SUPPORT_OVRHDR
81 push {lr}
82 bl ovrtimer_stop
83 pop {lr}
84#endif /* TOPPERS_SUPPORT_OVRHDR */
85 /*
86 *
87 * このルーチンは,PendSVによって呼び出される
88 * * Handler mode
89 * * use msp
90 * * lr = EXC_RETURN
91 * * scratch registers -> psp
92 * * CONTROL.FPCA -> EXC_RETURN && CONTROL.FPCA == 0
93 */
94 cpsid f /* FAULTMASK = 1 */
95 /*
96 * PendSV要求をクリア
97 * _dispatch - cpsid f の間でISRがå…
98¥ã‚Šï¼Œã•ã‚‰ã«PendSV要求が
99 * å…
100¥ã£ãŸå ´åˆã«ï¼Œdispatcherが無駄に走ることを防ぐため,
101 * ここでPendSV要求をクリアする
102 */
103 ldr r1, =0x08000000 /* r1 = ICSR.PENDSVCLR */
104 ldr r2, =0xE000ED04 /* r2 = *ICSR */
105 str r1, [r2] /* *ICSR = PENDSVCLR */
106
107 mrs r3, psp
108 stmfd r3!, {r4-r11} /* レジスタの保存 */
109#ifdef __TARGET_FPU_VFPUV4_D16
110 /*
111 * 呼出しå…
112ƒã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§æµ®å‹•å°æ•°ç‚¹æ¼”算をしたか?
113 * EXC_RETURN[4]をチェック
114 */
115 tst lr, #0x10
116 /* EXC_RETURN[4] == 1ならばスキップ */
117 bne _dispatch_1
118 vstmdb r3!, {s16-s31} /* レジスタの保存 */
119 /*fpscrは例外フレームに保存済み*/
120ALABEL(_dispatch_1)
121#endif /* __TARGET_FPU_VFPUV4_D16 */
122 ldr r1, =p_runtsk /* p_runtskを読み込む */
123 ldr r1, [r1]
124 str r3, [r1,#TCB_sp] /* タスクのスタックを保存 */
125 str lr, [r1,#TCB_pc]
126 b dispatcher
127
128/*
129 * CPU例外エントリ
130 *
131 * 割込みエントリと処理の内
132容は同等だが,ログの種類が異なるため,
133 * 分けている.
134 */
135 AALIGN(2)
136 ATEXT
137 ATHUMB(core_exc_entry)
138 AGLOBAL(core_exc_entry)
139ALABEL(core_exc_entry)
140 /*
141 * 例外/割込みが発生すると,発生時にアクティブなスタックにスクラ
142 * ッチレジスタ等が保存される.
143 * この内
144容に加えて,CPU例外ハンドラへの情
145報として,basepri の値と,
146 * EXC_RETURNの情
147報を加えて保存する.basepriの値は,CPU例外からの
148 * リターン時に割込み優å…
149ˆåº¦ãƒžã‚¹ã‚¯ã®å€¤ã‚’å…
150ƒã«æˆ»ã™ãŸã‚ã«ã‚‚用いられる.
151 *
152 * -----------
153 * | EXC_RETURN|
154 * -----------
155 * | basepri |
156 * -----------
157 * | R0 |
158 * -----------
159 * | R1 |
160 * -----------
161 * | R2 |
162 * -----------
163 * | R3 |
164 * -----------
165 * | R12 |
166 * -----------
167 * | LR |
168 * -----------
169 * | PC |
170 * -----------
171 * | xPSR |
172 * -----------
173 *
174 */
175
176 /*
177 * カーネル管理外の例外かチェック
178 * カーネル内
179のクリティカルセクションの実行中,å…
180¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
181‹ï¼Œ
182 * CPUロック状æ…
183‹ï¼Œã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–の割込みハンドラ実行中のいずれかで
184 * 発生したCPU例外を,カーネル管理外のCPU例外と呼ぶ
185 * å…
186¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
187‹ã¯FAULTMASKが'1'の場合
188 * CPUロック状æ…
189‹ã¯basepriがIIPM_LOCKかで判断する.
190 */
191 mrs r2, FAULTMASK /* å…
192¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
193‹ãªã‚‰ã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–例外処理へ */
194 cbnz r2, core_nonkernel_exc_entry
195
196 mrs r2, basepri /* baepriの値を取得 */
197 cmp r2, #IIPM_LOCK /* CPUロック状æ…
198‹ãªã‚‰ã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–例外処理へ */
199 beq core_nonkernel_exc_entry
200
201
202 /*
203 * スタックを変更する必
204要があるかチェック
205 * EXC_RETURN(割込み時にLRに設定される値)をチェックして,例外発生時に
206 * アクティブなスタックを特定することで多重割込みか判定する.
207 */
208 tst lr, #EXC_RETURN_PSP /* 割込みå…
209ƒãŒMSPなら多重割込み */
210 beq core_exc_entry_1 /* 多重割込みならcore_exc_entry_1へ */
211 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
212 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
213ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
214 stmfd r0!,{lr} /* EXC_RETURN を積む */
215 msr psp, r0 /* CPU例外ハンドラへの引数となる */
216 push {lr} /* MSP上にもEXC_RETURN を積む */
217#ifdef TOPPERS_SUPPORT_OVRHDR
218 push {r0}
219 bl ovrtimer_stop
220 pop {r0}
221#endif /* TOPPERS_SUPPORT_OVRHDR */
222 b core_exc_entry_2
223ALABEL(core_exc_entry_1) /* 多重割込みの場合 */
224 push {r2} /* 割込み発生時の割込み優å…
225ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
226 push {lr} /* EXC_RETURN を積む */
227 mov r0, sp /* CPU例外ハンドラへの引数となる */
228
229 /*
230 * å…
231±é€šå‡¦ç†
232 */
233ALABEL(core_exc_entry_2)
234 mrs r3, ipsr /* ハンドラアドレスを取得 */
235ALABEL(core_exc_entry_3)
236 ldr r1, =_kernel_exc_tbl
237 ldr r2, [r1, r3, lsl #2]
238
239#ifdef LOG_EXC_ENTER
240 push {r0,r2,r3}
241 mov r0, r3 /* 例外番号をパラメータに */
242 bl log_exc_enter /* log_exc_enterを呼び出す */
243 pop {r0,r2,r3}
244 push {r3} /* 例外番号をスタックへ */
245#endif /* LOG_EXC_ENTER */
246
247 /*
248 * CPU例外ハンドラの呼び出し
249 */
250 blx r2
251
252#ifdef LOG_EXC_ENTER
253 pop {r0} /* 例外番号を引数に */
254 bl log_exc_leave /* log_exc_leaveを呼び出す */
255#endif /* LOG_EXC_ENTER */
256
257 b ret_exc
258
259/*
260 * カーネル管理外のCPU例外の出å…
261¥å£å‡¦ç†
262 */
263ALABEL(core_nonkernel_exc_entry)
264 tst lr, #EXC_RETURN_PSP /* 割込みå…
265ƒãŒMSPなら多重割込み */
266 beq core_nonkernel_exc_entry_1 /* 多重割込みなら */
267 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
268 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
269ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
270 stmfd r0!,{lr} /* EXC_RETURN を積む */
271 msr psp, r0 /* CPU例外ハンドラへの引数となる */
272 push {lr} /* MSP上にもEXC_RETURN を積む */
273 b core_nonkernel_exc_entry_2
274ALABEL(core_nonkernel_exc_entry_1) /* 多重割込みの場合 */
275 push {r2} /* 割込み発生時の割込み優å…
276ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
277 push {lr} /* EXC_RETURN を積む */
278 mov r0, sp /* CPU例外ハンドラへの引数となる */
279
280ALABEL(core_nonkernel_exc_entry_2)
281 mrs r3, ipsr /* CPU例外ハンドラのアドレスを取得 */
282 ldr r1, =_kernel_exc_tbl
283 ldr r2, [r1, r3, lsl #2]
284
285 /*
286 * CPU例外ハンドラの呼び出し
287 */
288 blx r2
289
290 /*
291 * 割込みロック状æ…
292‹ã¨ã™ã‚‹ï¼Ž
293 */
294 cpsid f
295
296 /*
297 * 戻りå…
298ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®åˆ¤å®š
299 *
300 * 割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして,戻り
301 * å…
302ˆã§MSPが使われていれば,割込みå…
303ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã¨åˆ¤å®šã™ã‚‹ï¼Ž
304 */
305 pop {r3} /* lrをスタックから取得 */
306 tst r3, #EXC_RETURN_PSP /* 戻りå…
307ˆãŒPSPなら */
308 bne core_nonkernel_ret_exc_1
309 pop {r1} /* å…
310ƒã®å‰²è¾¼ã¿å„ªå…
311ˆåº¦ãƒžã‚¹ã‚¯(basepri) */
312 b core_nonkernel_ret_exc_2 /* の値をMSPから取得 */
313
314ALABEL(core_nonkernel_ret_exc_1)
315 /*
316 * PSP上からEXC_RETURNを削除
317 */
318 mrs r2, psp
319 add r2, r2, #4
320 /*
321 * å…
322ƒã®å‰²è¾¼ã¿å„ªå…
323ˆåº¦ãƒžã‚¹ã‚¯(basepri)の値をPSPから取得
324 */
325 ldmfd r2!, {r1}
326 msr psp, r2
327
328ALABEL(core_nonkernel_ret_exc_2)
329 msr basepri, r1 /* 割込み優å…
330ˆåº¦ãƒžã‚¹ã‚¯ã‚’割込み前に状æ…
331‹ã¸ */
332 bx r3 /* リターン */
333
334/*
335 * 割込みエントリ
336 */
337 ATHUMB(core_int_entry)
338 AGLOBAL(core_int_entry)
339ALABEL(core_int_entry)
340 /*
341 * 割込み発生時の割込み優å…
342ˆåº¦ãƒžã‚¹ã‚¯ã‚’スタックに保存するため取得
343 */
344 mrs r2, basepri /* baepriの値を取得 */
345
346 /*
347 * 多重割込みかチェック
348 * EXC_RETURN(割込み時にLRに設定される値)をチェックして,例外発生時に
349 * アクティブなスタックを特定することで多重割込みか判定する.
350 */
351 tst lr, #EXC_RETURN_PSP /* 割込みå…
352ƒãŒMSPなら多重割込み */
353 beq core_int_entry_1 /* 多重割込みならcore_int_entry_1へ */
354 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
355 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
356ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
357 stmfd r0!,{lr} /* EXC_RETURN を積む */
358 msr psp, r0 /* CPU例外ハンドラへの引数となる */
359 push {lr} /* MSP上にもEXC_RETURN を積む */
360#ifdef TOPPERS_SUPPORT_OVRHDR
361 push {r0}
362 bl ovrtimer_stop
363 pop {r0}
364#endif /* TOPPERS_SUPPORT_OVRHDR */
365 b core_int_entry_2
366ALABEL(core_int_entry_1) /* 多重割込みの場合 */
367 push {r2} /* 割込み発生時の割込み優å…
368ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
369 push {lr} /* EXC_RETURN を積む */
370 mov r0, sp /* 未定義の割込みが発生した場合の情
371報とする */
372
373 /*
374 * å…
375±é€šå‡¦ç†
376 */
377ALABEL(core_int_entry_2)
378 mrs r3, ipsr /* ハンドラアドレスを取得 */
379 ldr r1, =_kernel_exc_tbl
380 ldr r2, [r1, r3, lsl #2]
381
382 /*
383 * basepriの設定
384 * NVIC優å…
385ˆåº¦ãƒžã‚¹ã‚¯ãŒè‡ªå‹•çš„に設定されるため優å…
386ˆåº¦ãƒžã‚¹ã‚¯ã®ç‚¹ã§ã¯å¿…
387要な
388 * いが,x_get_ipm()がbasepriを参ç…
389§ã™ã‚‹ãŸã‚ï¼Œbasepriも更新する.
390 */
391 ldr r1, =_kernel_int_iipm_tbl
392 ldr lr, [r1, r3, lsl #2]
393 msr basepri, lr
394 isb
395
396#ifdef LOG_INH_ENTER
397 push {r0,r2,r3}
398 mov r0, r3 /* 例外番号をパラメータに */
399 bl log_inh_enter /* log_exc_enterを呼び出す */
400 pop {r0,r2,r3}
401 push {r3} /* 例外番号をスタックへ */
402#endif /* LOG_EXC_ENTER */
403
404 /*
405 * 割込みハンドラの呼び出し
406 */
407 blx r2
408
409#ifdef LOG_INH_LEAVE
410 pop {r0} /* 例外番号を引数に */
411 bl log_exc_leave /* log_exc_leaveを呼び出す */
412#endif /* LOG_INH_LEAVE */
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
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 * 割込みハンドラによりディスパッチ要求があった場合には,
477 * request_dispatchによって,PendSV要求が発行されている.
478 * その場合,このまま割込みハンドラからリターンした後,
479 * PendSVの割込みがå…
480¥ã‚Šï¼Œãã“でディスパッチャが実行される
481 * よって,ここではディスパッチするかどうかのチェック処理は
482 * 不要である
483 */
484
485#ifdef TOPPERS_SUPPORT_OVRHDR
486 push {r1,r3}
487 bl ovrtimer_start
488 pop {r1,r3}
489#endif /* TOPPERS_SUPPORT_OVRHDR */
490ALABEL(ret_int_2)
491 /*
492 * ここには割込みロック状æ…
493‹ï¼ˆFAULTMASKがセット)された状æ…
494‹ã§æ¥ã‚‹ï¼Ž
495 * Handlerモードからのリターンにより自動的に割込みロック解除状æ…
496‹ã«ãªã‚‹ï¼Ž
497 * 割込み優å…
498ˆåº¦ãƒžã‚¹ã‚¯ã¯å‰²è¾¼ã¿å‰ã«çŠ¶æ…
499‹ã«æˆ»ã™ï¼Ž
500 */
501 msr basepri, r1 /* 割込み優å…
502ˆåº¦ãƒžã‚¹ã‚¯ã‚’割込み前の状æ…
503‹ã¸ */
504 bx r3 /* リターン */
505
506/*
507 * ディスパッチャの動作開始
508 */
509 ATHUMB(start_dispatch)
510 AGLOBAL(start_dispatch)
511ALABEL(start_dispatch)
512 /*
513 * このルーチンは,カーネル起動時に,すべての割込みを禁止した状æ…
514‹
515 * (割込みロック状æ…
516‹ã¨åŒç­‰ï¼‰ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Žã¾ãŸï¼Œå‰²è¾¼ã¿ãƒ¢ãƒ¼ãƒ‰ï¼ˆéž
517 * タスクコンテキストと同等)で呼び出されることを想定している.
518 *
519 * core_initializeで,lock_flagをtrueに,saved_iipmをIIPM_ENAALLに
520 * 初期化しているため,カーネル管理外の割込みを許可することで,
521 * CPUロック状æ…
522‹ãƒ»ï¼ˆãƒ¢ãƒ‡ãƒ«ä¸Šã®ï¼‰å‰²è¾¼ã¿å„ªå…
523ˆåº¦ãƒžã‚¹ã‚¯å…
524¨è§£é™¤çŠ¶æ…
525‹ã«ãªã‚‹ï¼Ž
526 * また,task_initializeでdisdspをfalseに初期化しているため,ディ
527 * スパッチ許可状æ…
528‹ã«ãªã£ã¦ã„る.
529 */
530 ldr r0,=istkpt /* MSPを初期化 */
531 ldr r1,[r0] /* start_dispatch呼び出し時に呼び出し用に */
532 msr msp, r1 /* 使用しているため初期化する */
533 /*
534 * スタックをIDが1のタスクのスタック領域に切り換える
535 */
536 mov r0, #CONTROL_PSP /* PSPを有効に */
537 msr control, r0
538 isb /* control の操作後に必
539要 */
540 ldr r1, =tinib_table
541 ldr sp, [r1, #TINIB_stk_bottom]
542 /*
543 * ID1のタスクがすでにactivate_contextされている場合,
544 * スタックのå…
545ˆé ­ã«spを初期化してしまうと,svcにより
546 * activate_contextで準備した内
547容が消されてしまうため,
548 * その分を飛ばしたアドレスを,カーネル動作開始時の
549 * スタックå…
550ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ã™ã‚‹
551 */
552 add sp, sp, #(4*16)
553 ldr r1, =IIPM_LOCK /* カーネル管理内
554の割込みを禁止 */
555 msr basepri, r1
556 isb
557 cpsie f /* カーネル管理外の割込みを許可 */
558 /*
559 * _exit_and_dispatchでCPUロック解除&FAULTMASK=1をしているにも
560 * かかわらず,ここでCPUロック&FAULTMASK=0としているのは,
561 * ディスパッチャをsvc発行時の状æ…
562‹ã§å‘¼ã‚“でおり,かつ,
563 * FAULTMASK状æ…
564‹ã§svcを発行するとdouble faultでリセットがかかる
565 * ためである
566 */
567
568 ATHUMB(exit_and_dispatch)
569 AGLOBAL(exit_and_dispatch)
570ALABEL(exit_and_dispatch)
571 /*
572 * r3=pspはsvcの発行後でもよいが,スタック使用量が多くなるため,
573 * svc前のpspをr3に保存しておく
574 */
575 svc #NO_DISPATCHER
576
577/*
578 * 現在のコンテキストを捨ててディスパッチ
579 */
580 ATHUMB(_exit_and_dispatch)
581 AGLOBAL(_exit_and_dispatch)
582ALABEL(_exit_and_dispatch)
583 cpsid f /* FAULTMASK = 1 */
584 mov r0, #0
585 ldr r1, =lock_flag /* CPUロック解除状æ…
586‹ã¸ */
587 str r0, [r1]
588 ldr r1, =IIPM_ENAALL /* 割込み優å…
589ˆåº¦ãƒžã‚¹ã‚¯ã‚’å…
590¨è§£é™¤çŠ¶æ…
591‹ã«è¨­å®š */
592 msr basepri, r1
593 mrs r3, psp
594 /* ディスパッチャ本体(dispatcher)へ */
595
596/*
597 * ディスパッチャ本体
598 */
599 ATHUMB(dispatcher)
600 AGLOBAL(dispatcher)
601ALABEL(dispatcher)
602 /*
603 * このルーチンは,タスクコンテキスト・CPUロック状æ…
604‹ãƒ»ãƒ‡ã‚£ã‚¹ãƒ‘ッチ
605 * 許可状æ…
606‹ãƒ»ï¼ˆãƒ¢ãƒ‡ãƒ«ä¸Šã®ï¼‰å‰²è¾¼ã¿å„ªå…
607ˆåº¦ãƒžã‚¹ã‚¯å…
608¨è§£é™¤çŠ¶æ…
609‹ã§å‘¼ã³å‡ºã•
610 * れる.
611 *
612 * すなわち,Handlerモード・lock_flagがtrue・disdspがfalse・dspflg
613 * がtrue・saved_iipmがIIPM_ENAALLとなっている.実行再開番地へもこ
614 * の状æ…
615‹ã®ã¾ã¾åˆ†å²ã™ã‚‹ï¼Ž
616 * また,MSPは,istkpt(初期値)となっている
617 *
618 * from dispatch:
619 * svc命令によりHandlerモードとなり,pspに戻りå…
620ˆç•ªåœ°dispatch_rを
621 * 積んだ状æ…
622‹ï¼ˆTCB.spにpspを,TCB.pcにEXC_RETURN_PSPを保存済み)
623 * from start_dispatch/exit_and_dispatch:
624 * svc命令によりHandlerモードとなった状æ…
625‹
626 * (以前に実行状æ…
627‹ã§ã‚ったタスクorID0のタスクのスタックに戻りå…
628ˆ
629 * などが積まれるが,次回にタスクを起動する際に破棄される)
630 * from ret_int:
631 * すでにHandlerモードであるため,単なるジャンプ命令でここにくる
632 * (TCB.spにpspを,TCB.pcにret_int_rを保存済み)
633
634 * to dispatch_r:
635 * TCB.pcからEXC_RETURN_PSPをロードし,bx命令によりリターンする
636 * ことで,Threadモードとなり,TCB.spのpspに積まれたdispatch_r
637 * に戻る(TCB.pc/spはdispatchでセット済み)
638 * to start_r:
639 * TCB.pcからstart_rをロードし,bx命令によりジャンプしたあと,
640 * タスク起動時の引数レジスタ値,pcをTCB.spのpspに積み,bx
641 * EXC_RETURN_PSP 命令によってThreadモードとなり,タスク起動番地
642 * へジャンプする
643 * (TCB.pc/spはactivate_contextでセット済み)
644 * to ret_int_r:
645 * TCB.pcからret_int_rをロードし,bx命令によりジャンプしたあと,
646 * 割込みハンドラの出口処理により,Threadモードに戻り,割込みå…
647ƒã«
648 * 戻る(TCB.pc/spはret_intでセット済み)
649 */
650#ifdef TOPPERS_SUPPORT_OVRHDR
651 bl ovrtimer_stop
652#endif /* TOPPERS_SUPPORT_OVRHDR */
653#ifdef LOG_DSP_ENTER
654 ldr r1, =p_runtsk /* p_runtskをパラメータに */
655 ldr r0, [r1]
656 bl log_dsp_enter
657#endif /* LOG_DSP_ENTER */
658ALABEL(dispatcher_0)
659 ldr r0, =p_schedtsk /* p_schedtskをp_runtskに */
660 ldr r1, [r0]
661 ldr r2, =p_runtsk
662 str r1, [r2]
663 cbz r1, idle_loop /* p_runtskがNULLならidle_loopへ */
664 ldr lr, [r1,#TCB_pc] /* 実行再開番地を復帰 */
665 ldr r0, [r1,#TCB_sp] /* タスクのスタックを復帰 */
666#ifdef __TARGET_FPU_VFPUV4_D16
667 /*
668 * 戻りå…
669ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§æµ®å‹•å°æ•°ç‚¹æ¼”算をしたか?
670 * EXC_RETURN[4]をチェック
671 */
672 tst lr, #0x10
673 /* EXC_RETURN[4] == 1ならばスキップ */
674 bne dispatcher_2
675 /*fpscrは例外フレームから復帰する*/
676 vldmia r0!, {s16-s31} /* レジスタの復帰 */
677ALABEL(dispatcher_2)
678#endif /* __TARGET_FPU_VFPUV4_D16 */
679 ldmfd r0!, {r4-r11} /* レジスタの復帰 */
680 msr psp, r0 /* psp = p_runtsk->sp */
681
682#ifdef LOG_DSP_LEAVE
683 mov r0, r1 /* p_runtskをパラメータに */
684 mov r4, r1 /* r1はスクラッチレジスタなので保存 */
685 bl log_dsp_leave
686 mov r1, r4
687#endif /* LOG_DSP_LEAVE */
688#ifdef TOPPERS_SUPPORT_OVRHDR
689 push {lr}
690 bl ovrtimer_start
691 pop {lr}
692#endif /* TOPPERS_SUPPORT_OVRHDR */
693 /*
694 * ARM<->Thumbモード変換を抑制するためにpcに直接戻り番地を
695 * å…
696¥ã‚Œã‚‹
697 * 割込みå…
698ƒã«æˆ»ã‚‹å ´åˆã«ãŠã„ても,EXC_RETURNを直接pcに代å…
699¥ã—て
700 * (bx命令を使わずに戻っても)問題ない
701 */
702 bx lr /* 実行再開番地を復帰 */
703
704ALABEL(idle_loop)
705 /*
706 * 割込みを許可したらCPUロック解除状æ…
707‹ã«ãªã‚‹ã‚ˆã†æº–備する
708 * CPUロック状æ…
709‹ã®è§£é™¤ã¨ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå®Ÿè¡ŒçŠ¶æ…
710‹ã¸ã®
711 * 準備をする
712 */
713 /*
714 * pspにダミーフレームを積んでbx lrにより,threadモードかつidleへ
715 * この時点では,r3=pspである
716 * r3には,dispatchでcallee-saved-registerが保存されたあとの
717 * スタックポインタがå…
718¥ã£ã¦ãŠã‚Šï¼Œãã®ç¶šãã‹ã‚‰ã‚¹ã‚¿ãƒƒã‚¯ã‚’使用する
719 */
720 ldr r0, =_idle_loop /* PC */
721 ldr r1, =EPSR_T /* xPSR(Tビットが'1'である必
722要がある) */
723 /*
724 * アイドルループ中のFPは任意なので設定しない
725 */
726 ldr lr, =0xfffffffd
727 stmfd r3!, {r0-r1} /* ダミーフレームをスタック上に積む */
728 sub r3, #(6*4) /* r0-r3,r12,lrの内
729容は設定する必
730要がない */
731 msr psp, r3
732 bx lr
733
734ALABEL(_idle_loop)
735 /* ここではすでに割込み許可状æ…
736‹ */
737#ifdef TOPPERS_CUSTOM_IDLE
738 toppers_asm_custom_idle
739#else
740ALABEL(_idle_loop_1)
741 /*
742 * basepriをå…
743¨å‰²è¾¼ã¿è¨±å¯ã«è¨­å®šã—てからwfiが発行されるまでに
744 * 割込みがå…
745¥ã£ãŸå ´åˆï¼Œãã“でディスパッチが必
746要な状æ…
747‹ã«ãªã‚Œã°
748 * 割込みの出口処理で遅
749延ディスパッチし,ここには戻ってこない.
750 * 遅
751延ディスパッチしなかった場合はここに戻ってきて次の割込みを
752 * wfiで待
753つため,想定どおりの動作となる
754 */
755 wfi
756 b _idle_loop_1
757 nop
758#endif /* TOPPERS_CUSTOM_IDLE */
759
760/*
761 * カーネルの終了処理の呼出し
762 *
763 * スタックを非タスクコンテキスト用に切り替え.
764 *
765 */
766 ATHUMB(call_exit_kernel)
767 AGLOBAL(call_exit_kernel)
768ALABEL(call_exit_kernel)
769 mov r0, #CONTROL_MSP
770 msr control, r0 /* MSPを有効に */
771 isb /* control の操作後に必
772要 */
773 ldr r0, =exit_kernel /* カーネルの終了処理を呼ぶ */
774 bx r0
775
776/*
777 * 微少時間待
778ち
779 */
780 AALIGN(2)
781 ATEXT
782 ATHUMB(sil_dly_nse)
783 AGLOBAL(sil_dly_nse)
784ALABEL(sil_dly_nse)
785 sub r0, r0, #SIL_DLY_TIM1
786 cmp r0, #0
787 bgt sil_dly_nse1
788 bx lr
789ALABEL(sil_dly_nse1)
790 sub r0, r0, #SIL_DLY_TIM2
791 cmp r0, #0
792 bgt sil_dly_nse1
793 bx lr
794
Note: See TracBrowser for help on using the repository browser.