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

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

TECSレスのASP3の開発のため以下のtrunkからコピー
http://dev.toppers.jp/svn/asp3/branches/WO_TECS-3.C.0

File size: 25.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-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 mrs r3, psp
96 stmfd r3!, {r4-r11} /* レジスタの保存 */
97#ifdef __TARGET_FPU_VFPUV4_D16
98 /*
99 * 呼出しå…
100ƒã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§æµ®å‹•å°æ•°ç‚¹æ¼”算をしたか?
101 * EXC_RETURN[4]をチェック
102 */
103 tst lr, #0x10
104 /* EXC_RETURN[4] == 1ならばスキップ */
105 bne _dispatch_1
106 vstmdb r3!, {s16-s31} /* レジスタの保存 */
107 /*fpscrは例外フレームに保存済み*/
108ALABEL(_dispatch_1)
109#endif /* __TARGET_FPU_VFPUV4_D16 */
110 ldr r1, =p_runtsk /* p_runtskを読み込む */
111 ldr r1, [r1]
112 str r3, [r1,#TCB_sp] /* タスクのスタックを保存 */
113 str lr, [r1,#TCB_pc]
114 b dispatcher
115
116/*
117 * CPU例外エントリ
118 *
119 * 割込みエントリと処理の内
120容は同等だが,ログの種類が異なるため,
121 * 分けている.
122 */
123 AALIGN(2)
124 ATEXT
125 ATHUMB(core_exc_entry)
126 AGLOBAL(core_exc_entry)
127ALABEL(core_exc_entry)
128 /*
129 * 例外/割込みが発生すると,発生時にアクティブなスタックにスクラ
130 * ッチレジスタ等が保存される.
131 * この内
132容に加えて,CPU例外ハンドラへの情
133報として,basepri の値と,
134 * EXC_RETURNの情
135報を加えて保存する.basepriの値は,CPU例外からの
136 * リターン時に割込み優å…
137ˆåº¦ãƒžã‚¹ã‚¯ã®å€¤ã‚’å…
138ƒã«æˆ»ã™ãŸã‚ã«ã‚‚用いられる.
139 *
140 * -----------
141 * | EXC_RETURN|
142 * -----------
143 * | basepri |
144 * -----------
145 * | R0 |
146 * -----------
147 * | R1 |
148 * -----------
149 * | R2 |
150 * -----------
151 * | R3 |
152 * -----------
153 * | R12 |
154 * -----------
155 * | LR |
156 * -----------
157 * | PC |
158 * -----------
159 * | xPSR |
160 * -----------
161 *
162 */
163
164 /*
165 * カーネル管理外の例外かチェック
166 * カーネル内
167のクリティカルセクションの実行中,å…
168¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
169‹ï¼Œ
170 * CPUロック状æ…
171‹ï¼Œã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–の割込みハンドラ実行中のいずれかで
172 * 発生したCPU例外を,カーネル管理外のCPU例外と呼ぶ
173 * å…
174¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
175‹ã¯FAULTMASKが'1'の場合
176 * CPUロック状æ…
177‹ã¯basepriがIIPM_LOCKかで判断する.
178 */
179 mrs r2, FAULTMASK /* å…
180¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
181‹ãªã‚‰ã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–例外処理へ */
182 cbnz r2, core_nonkernel_exc_entry
183
184 mrs r2, basepri /* baepriの値を取得 */
185 cmp r2, #IIPM_LOCK /* CPUロック状æ…
186‹ãªã‚‰ã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–例外処理へ */
187 beq core_nonkernel_exc_entry
188
189
190 /*
191 * スタックを変更する必
192要があるかチェック
193 * EXC_RETURN(割込み時にLRに設定される値)をチェックして,例外発生時に
194 * アクティブなスタックを特定することで多重割込みか判定する.
195 */
196 tst lr, #EXC_RETURN_PSP /* 割込みå…
197ƒãŒMSPなら多重割込み */
198 beq core_exc_entry_1 /* 多重割込みならcore_exc_entry_1へ */
199 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
200 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
201ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
202 stmfd r0!,{lr} /* EXC_RETURN を積む */
203 msr psp, r0 /* CPU例外ハンドラへの引数となる */
204 push {lr} /* MSP上にもEXC_RETURN を積む */
205#ifdef TOPPERS_SUPPORT_OVRHDR
206 push {r0}
207 bl ovrtimer_stop
208 pop {r0}
209#endif /* TOPPERS_SUPPORT_OVRHDR */
210 b core_exc_entry_2
211ALABEL(core_exc_entry_1) /* 多重割込みの場合 */
212 push {r2} /* 割込み発生時の割込み優å…
213ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
214 push {lr} /* EXC_RETURN を積む */
215 mov r0, sp /* CPU例外ハンドラへの引数となる */
216
217 /*
218 * å…
219±é€šå‡¦ç†
220 */
221ALABEL(core_exc_entry_2)
222 mrs r3, ipsr /* ハンドラアドレスを取得 */
223ALABEL(core_exc_entry_3)
224 ldr r1, =_kernel_exc_tbl
225 ldr r2, [r1, r3, lsl #2]
226
227#ifdef LOG_EXC_ENTER
228 push {r0,r2,r3}
229 mov r0, r3 /* 例外番号をパラメータに */
230 bl log_exc_enter /* log_exc_enterを呼び出す */
231 pop {r0,r2,r3}
232 push {r3} /* 例外番号をスタックへ */
233#endif /* LOG_EXC_ENTER */
234
235 /*
236 * CPU例外ハンドラの呼び出し
237 */
238 blx r2
239
240#ifdef LOG_EXC_ENTER
241 pop {r0} /* 例外番号を引数に */
242 bl log_exc_leave /* log_exc_leaveを呼び出す */
243#endif /* LOG_EXC_ENTER */
244
245 b ret_exc
246
247/*
248 * カーネル管理外のCPU例外の出å…
249¥å£å‡¦ç†
250 */
251ALABEL(core_nonkernel_exc_entry)
252 tst lr, #EXC_RETURN_PSP /* 割込みå…
253ƒãŒMSPなら多重割込み */
254 beq core_nonkernel_exc_entry_1 /* 多重割込みなら */
255 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
256 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
257ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
258 stmfd r0!,{lr} /* EXC_RETURN を積む */
259 msr psp, r0 /* CPU例外ハンドラへの引数となる */
260 push {lr} /* MSP上にもEXC_RETURN を積む */
261 b core_nonkernel_exc_entry_2
262ALABEL(core_nonkernel_exc_entry_1) /* 多重割込みの場合 */
263 push {r2} /* 割込み発生時の割込み優å…
264ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
265 push {lr} /* EXC_RETURN を積む */
266 mov r0, sp /* CPU例外ハンドラへの引数となる */
267
268ALABEL(core_nonkernel_exc_entry_2)
269 mrs r3, ipsr /* CPU例外ハンドラのアドレスを取得 */
270 ldr r1, =_kernel_exc_tbl
271 ldr r2, [r1, r3, lsl #2]
272
273 /*
274 * CPU例外ハンドラの呼び出し
275 */
276 blx r2
277
278 /*
279 * 割込みロック状æ…
280‹ã¨ã™ã‚‹ï¼Ž
281 */
282 cpsid f
283
284 /*
285 * 戻りå…
286ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®åˆ¤å®š
287 *
288 * 割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして,戻り
289 * å…
290ˆã§MSPが使われていれば,割込みå…
291ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã¨åˆ¤å®šã™ã‚‹ï¼Ž
292 */
293 pop {r3} /* lrをスタックから取得 */
294 tst r3, #EXC_RETURN_PSP /* 戻りå…
295ˆãŒPSPなら */
296 bne core_nonkernel_ret_exc_1
297 pop {r1} /* å…
298ƒã®å‰²è¾¼ã¿å„ªå…
299ˆåº¦ãƒžã‚¹ã‚¯(basepri) */
300 b core_nonkernel_ret_exc_2 /* の値をMSPから取得 */
301
302ALABEL(core_nonkernel_ret_exc_1)
303 /*
304 * PSP上からEXC_RETURNを削除
305 */
306 mrs r2, psp
307 add r2, r2, #4
308 /*
309 * å…
310ƒã®å‰²è¾¼ã¿å„ªå…
311ˆåº¦ãƒžã‚¹ã‚¯(basepri)の値をPSPから取得
312 */
313 ldmfd r2!, {r1}
314 msr psp, r2
315
316ALABEL(core_nonkernel_ret_exc_2)
317 msr basepri, r1 /* 割込み優å…
318ˆåº¦ãƒžã‚¹ã‚¯ã‚’割込み前に状æ…
319‹ã¸ */
320 bx r3 /* リターン */
321
322/*
323 * 割込みエントリ
324 */
325 ATHUMB(core_int_entry)
326 AGLOBAL(core_int_entry)
327ALABEL(core_int_entry)
328 /*
329 * 割込み発生時の割込み優å…
330ˆåº¦ãƒžã‚¹ã‚¯ã‚’スタックに保存するため取得
331 */
332 mrs r2, basepri /* baepriの値を取得 */
333
334 /*
335 * 多重割込みかチェック
336 * EXC_RETURN(割込み時にLRに設定される値)をチェックして,例外発生時に
337 * アクティブなスタックを特定することで多重割込みか判定する.
338 */
339 tst lr, #EXC_RETURN_PSP /* 割込みå…
340ƒãŒMSPなら多重割込み */
341 beq core_int_entry_1 /* 多重割込みならcore_int_entry_1へ */
342 mrs r0, psp /* 一段目の割込みの場合はPSP上に */
343 stmfd r0!,{r2} /* 割込み発生時の割込み優å…
344ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
345 stmfd r0!,{lr} /* EXC_RETURN を積む */
346 msr psp, r0 /* CPU例外ハンドラへの引数となる */
347 push {lr} /* MSP上にもEXC_RETURN を積む */
348#ifdef TOPPERS_SUPPORT_OVRHDR
349 push {r0}
350 bl ovrtimer_stop
351 pop {r0}
352#endif /* TOPPERS_SUPPORT_OVRHDR */
353 b core_int_entry_2
354ALABEL(core_int_entry_1) /* 多重割込みの場合 */
355 push {r2} /* 割込み発生時の割込み優å…
356ˆåº¦ãƒžã‚¹ã‚¯ã‚’積む */
357 push {lr} /* EXC_RETURN を積む */
358 mov r0, sp /* 未定義の割込みが発生した場合の情
359報とする */
360
361 /*
362 * å…
363±é€šå‡¦ç†
364 */
365ALABEL(core_int_entry_2)
366 mrs r3, ipsr /* ハンドラアドレスを取得 */
367 ldr r1, =_kernel_exc_tbl
368 ldr r2, [r1, r3, lsl #2]
369
370 /*
371 * basepriの設定
372 * NVIC優å…
373ˆåº¦ãƒžã‚¹ã‚¯ãŒè‡ªå‹•çš„に設定されるため優å…
374ˆåº¦ãƒžã‚¹ã‚¯ã®ç‚¹ã§ã¯å¿…
375要な
376 * いが,x_get_ipm()がbasepriを参ç…
377§ã™ã‚‹ãŸã‚ï¼Œbasepriも更新する.
378 */
379 ldr r1, =_kernel_int_iipm_tbl
380 ldr lr, [r1, r3, lsl #2]
381 msr basepri, lr
382 isb
383
384#ifdef LOG_INH_ENTER
385 push {r0,r2,r3}
386 mov r0, r3 /* 例外番号をパラメータに */
387 bl log_inh_enter /* log_exc_enterを呼び出す */
388 pop {r0,r2,r3}
389 push {r3} /* 例外番号をスタックへ */
390#endif /* LOG_EXC_ENTER */
391
392 /*
393 * 割込みハンドラの呼び出し
394 */
395 blx r2
396
397#ifdef LOG_INH_LEAVE
398 pop {r0} /* 例外番号を引数に */
399 bl log_exc_leave /* log_exc_leaveを呼び出す */
400#endif /* LOG_INH_LEAVE */
401
402/*
403 * 割込み/例外出口
404 *
405 * ret_exc/ret_intは,CPU例外/割込みハンドラから戻った直後に実行する
406 * ルーチンである.
407 */
408ALABEL(ret_exc)
409ALABEL(ret_int)
410 /*
411 * 割込みロック状æ…
412‹ã¨ã™ã‚‹ï¼Žã“の時点では,CPUロック状æ…
413‹ã«ã¯ãªã‚‰ãªã„
414 * (basepriとlock_flagとsaved_iipmは更新しない).
415 *
416 * 割込みロック状æ…
417‹ã¨ã™ã‚‹ã®ã¯ï¼Œæˆ»ã‚Šå…
418ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®ãƒã‚§ãƒƒã‚¯ã¨ï¼Œ
419 * 戻りå…
420ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§ã‚った場合のリターンをアトミック
421 * に行うためである.bsepriをCPUロックの値にすることでもアトミッ
422 * クなチェックと復帰は可能であるが,割込みからリターンしても,
423 * basepri の設定内
424容はå…
425ƒã«æˆ»ã‚‰ãªã„ため,使用することができない.
426 * 一方,FAULTMASKは,割込みからのリターン処理によって,'0'にクリ
427 * アされる.
428 */
429 cpsid f
430
431 /*
432 * 戻りå…
433ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã®åˆ¤å®š
434 *
435 * 割込みハンドラ実行にLRにセットされるEXC_RETURNをチェックして,戻り
436 * å…
437ˆã§MSPが使われていれば,割込みå…
438ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã¨åˆ¤å®šã™ã‚‹ï¼Ž
439 */
440 pop {r3} /* lrをスタックから取得 */
441 tst r3, #EXC_RETURN_PSP /* 戻りå…
442ˆãŒPSPなら ret_int_1 へ */
443 bne ret_int_1
444 pop {r1} /* å…
445ƒã®å‰²è¾¼ã¿å„ªå…
446ˆåº¦ãƒžã‚¹ã‚¯(basepri)をr1へ */
447 b ret_int_2
448
449 /*
450 * 一段目の割込みの出口処理
451 */
452ALABEL(ret_int_1)
453 /*
454 * PSP上から,EXC_RETURN(r0)とå…
455ƒã®å‰²è¾¼ã¿å„ªå…
456ˆåº¦ãƒžã‚¹ã‚¯(basepri)(r1)
457 * を取得
458 */
459 mrs r2, psp
460 ldmfd r2!, {r0,r1}
461 msr psp, r2
462
463 /*
464 * 割込みハンドラによりディスパッチ要求があった場合には,
465 * request_dispatchによって,PendSV要求が発行されている.
466 * その場合,このまま割込みハンドラからリターンした後,
467 * PendSVの割込みがå…
468¥ã‚Šï¼Œãã“でディスパッチャが実行される
469 * よって,ここではディスパッチするかどうかのチェック処理は
470 * 不要である
471 */
472
473#ifdef TOPPERS_SUPPORT_OVRHDR
474 push {r1,r3}
475 bl ovrtimer_start
476 pop {r1,r3}
477#endif /* TOPPERS_SUPPORT_OVRHDR */
478ALABEL(ret_int_2)
479 /*
480 * ここには割込みロック状æ…
481‹ï¼ˆFAULTMASKがセット)された状æ…
482‹ã§æ¥ã‚‹ï¼Ž
483 * Handlerモードからのリターンにより自動的に割込みロック解除状æ…
484‹ã«ãªã‚‹ï¼Ž
485 * 割込み優å…
486ˆåº¦ãƒžã‚¹ã‚¯ã¯å‰²è¾¼ã¿å‰ã«çŠ¶æ…
487‹ã«æˆ»ã™ï¼Ž
488 */
489 msr basepri, r1 /* 割込み優å…
490ˆåº¦ãƒžã‚¹ã‚¯ã‚’割込み前の状æ…
491‹ã¸ */
492 bx r3 /* リターン */
493
494/*
495 * ディスパッチャの動作開始
496 */
497 ATHUMB(start_dispatch)
498 AGLOBAL(start_dispatch)
499ALABEL(start_dispatch)
500 /*
501 * このルーチンは,カーネル起動時に,すべての割込みを禁止した状æ…
502‹
503 * (割込みロック状æ…
504‹ã¨åŒç­‰ï¼‰ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Žã¾ãŸï¼Œå‰²è¾¼ã¿ãƒ¢ãƒ¼ãƒ‰ï¼ˆéž
505 * タスクコンテキストと同等)で呼び出されることを想定している.
506 *
507 * core_initializeで,lock_flagをtrueに,saved_iipmをIIPM_ENAALLに
508 * 初期化しているため,カーネル管理外の割込みを許可することで,
509 * CPUロック状æ…
510‹ãƒ»ï¼ˆãƒ¢ãƒ‡ãƒ«ä¸Šã®ï¼‰å‰²è¾¼ã¿å„ªå…
511ˆåº¦ãƒžã‚¹ã‚¯å…
512¨è§£é™¤çŠ¶æ…
513‹ã«ãªã‚‹ï¼Ž
514 * また,task_initializeでdisdspをfalseに初期化しているため,ディ
515 * スパッチ許可状æ…
516‹ã«ãªã£ã¦ã„る.
517 */
518 ldr r0,=istkpt /* MSPを初期化 */
519 ldr r1,[r0] /* start_dispatch呼び出し時に呼び出し用に */
520 msr msp, r1 /* 使用しているため初期化する */
521 /*
522 * スタックをIDが1のタスクのスタック領域に切り換える
523 */
524 mov r0, #CONTROL_PSP /* PSPを有効に */
525 msr control, r0
526 isb /* control の操作後に必
527要 */
528 ldr r1, =tinib_table
529 ldr sp, [r1, #TINIB_stk_bottom]
530 /*
531 * ID1のタスクがすでにactivate_contextされている場合,
532 * スタックのå…
533ˆé ­ã«spを初期化してしまうと,svcにより
534 * activate_contextで準備した内
535容が消されてしまうため,
536 * その分を飛ばしたアドレスを,カーネル動作開始時の
537 * スタックå…
538ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ã™ã‚‹
539 */
540 add sp, sp, #(4*16)
541 ldr r1, =IIPM_LOCK /* カーネル管理内
542の割込みを禁止 */
543 msr basepri, r1
544 isb
545 cpsie f /* カーネル管理外の割込みを許可 */
546 /*
547 * _exit_and_dispatchでCPUロック解除&FAULTMASK=1をしているにも
548 * かかわらず,ここでCPUロック&FAULTMASK=0としているのは,
549 * ディスパッチャをsvc発行時の状æ…
550‹ã§å‘¼ã‚“でおり,かつ,
551 * FAULTMASK状æ…
552‹ã§svcを発行するとdouble faultでリセットがかかる
553 * ためである
554 */
555
556 ATHUMB(exit_and_dispatch)
557 AGLOBAL(exit_and_dispatch)
558ALABEL(exit_and_dispatch)
559 /*
560 * r3=pspはsvcの発行後でもよいが,スタック使用量が多くなるため,
561 * svc前のpspをr3に保存しておく
562 */
563 svc #NO_DISPATCHER
564
565/*
566 * 現在のコンテキストを捨ててディスパッチ
567 */
568 ATHUMB(_exit_and_dispatch)
569 AGLOBAL(_exit_and_dispatch)
570ALABEL(_exit_and_dispatch)
571 cpsid f /* FAULTMASK = 1 */
572 mov r0, #0
573 ldr r1, =lock_flag /* CPUロック解除状æ…
574‹ã¸ */
575 str r0, [r1]
576 ldr r1, =IIPM_ENAALL /* 割込み優å…
577ˆåº¦ãƒžã‚¹ã‚¯ã‚’å…
578¨è§£é™¤çŠ¶æ…
579‹ã«è¨­å®š */
580 msr basepri, r1
581 mrs r3, psp
582 /* ディスパッチャ本体(dispatcher)へ */
583
584/*
585 * ディスパッチャ本体
586 */
587 ATHUMB(dispatcher)
588 AGLOBAL(dispatcher)
589ALABEL(dispatcher)
590 /*
591 * このルーチンは,タスクコンテキスト・CPUロック状æ…
592‹ãƒ»ãƒ‡ã‚£ã‚¹ãƒ‘ッチ
593 * 許可状æ…
594‹ãƒ»ï¼ˆãƒ¢ãƒ‡ãƒ«ä¸Šã®ï¼‰å‰²è¾¼ã¿å„ªå…
595ˆåº¦ãƒžã‚¹ã‚¯å…
596¨è§£é™¤çŠ¶æ…
597‹ã§å‘¼ã³å‡ºã•
598 * れる.
599 *
600 * すなわち,Handlerモード・lock_flagがtrue・disdspがfalse・dspflg
601 * がtrue・saved_iipmがIIPM_ENAALLとなっている.実行再開番地へもこ
602 * の状æ…
603‹ã®ã¾ã¾åˆ†å²ã™ã‚‹ï¼Ž
604 * また,MSPは,istkpt(初期値)となっている
605 *
606 * from dispatch:
607 * svc命令によりHandlerモードとなり,pspに戻りå…
608ˆç•ªåœ°dispatch_rを
609 * 積んだ状æ…
610‹ï¼ˆTCB.spにpspを,TCB.pcにEXC_RETURN_PSPを保存済み)
611 * from start_dispatch/exit_and_dispatch:
612 * svc命令によりHandlerモードとなった状æ…
613‹
614 * (以前に実行状æ…
615‹ã§ã‚ったタスクorID0のタスクのスタックに戻りå…
616ˆ
617 * などが積まれるが,次回にタスクを起動する際に破棄される)
618 * from ret_int:
619 * すでにHandlerモードであるため,単なるジャンプ命令でここにくる
620 * (TCB.spにpspを,TCB.pcにret_int_rを保存済み)
621
622 * to dispatch_r:
623 * TCB.pcからEXC_RETURN_PSPをロードし,bx命令によりリターンする
624 * ことで,Threadモードとなり,TCB.spのpspに積まれたdispatch_r
625 * に戻る(TCB.pc/spはdispatchでセット済み)
626 * to start_r:
627 * TCB.pcからstart_rをロードし,bx命令によりジャンプしたあと,
628 * タスク起動時の引数レジスタ値,pcをTCB.spのpspに積み,bx
629 * EXC_RETURN_PSP 命令によってThreadモードとなり,タスク起動番地
630 * へジャンプする
631 * (TCB.pc/spはactivate_contextでセット済み)
632 * to ret_int_r:
633 * TCB.pcからret_int_rをロードし,bx命令によりジャンプしたあと,
634 * 割込みハンドラの出口処理により,Threadモードに戻り,割込みå…
635ƒã«
636 * 戻る(TCB.pc/spはret_intでセット済み)
637 */
638#ifdef TOPPERS_SUPPORT_OVRHDR
639 bl ovrtimer_stop
640#endif /* TOPPERS_SUPPORT_OVRHDR */
641#ifdef LOG_DSP_ENTER
642 ldr r1, =p_runtsk /* p_runtskをパラメータに */
643 ldr r0, [r1]
644 bl log_dsp_enter
645#endif /* LOG_DSP_ENTER */
646ALABEL(dispatcher_0)
647 ldr r0, =p_schedtsk /* p_schedtskをp_runtskに */
648 ldr r1, [r0]
649 ldr r2, =p_runtsk
650 str r1, [r2]
651 cbz r1, idle_loop /* p_runtskがNULLならidle_loopへ */
652 ldr lr, [r1,#TCB_pc] /* 実行再開番地を復帰 */
653 ldr r0, [r1,#TCB_sp] /* タスクのスタックを復帰 */
654#ifdef __TARGET_FPU_VFPUV4_D16
655 /*
656 * 戻りå…
657ˆã®ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã§æµ®å‹•å°æ•°ç‚¹æ¼”算をしたか?
658 * EXC_RETURN[4]をチェック
659 */
660 tst lr, #0x10
661 /* EXC_RETURN[4] == 1ならばスキップ */
662 bne dispatcher_2
663 /*fpscrは例外フレームから復帰する*/
664 vldmia r0!, {s16-s31} /* レジスタの復帰 */
665ALABEL(dispatcher_2)
666#endif /* __TARGET_FPU_VFPUV4_D16 */
667 ldmfd r0!, {r4-r11} /* レジスタの復帰 */
668 msr psp, r0 /* psp = p_runtsk->sp */
669
670#ifdef LOG_DSP_LEAVE
671 mov r0, r1 /* p_runtskをパラメータに */
672 mov r4, r1 /* r1はスクラッチレジスタなので保存 */
673 bl log_dsp_leave
674 mov r1, r4
675#endif /* LOG_DSP_LEAVE */
676#ifdef TOPPERS_SUPPORT_OVRHDR
677 push {lr}
678 bl ovrtimer_start
679 pop {lr}
680#endif /* TOPPERS_SUPPORT_OVRHDR */
681 /*
682 * ARM<->Thumbモード変換を抑制するためにpcに直接戻り番地を
683 * å…
684¥ã‚Œã‚‹
685 * 割込みå…
686ƒã«æˆ»ã‚‹å ´åˆã«ãŠã„ても,EXC_RETURNを直接pcに代å…
687¥ã—て
688 * (bx命令を使わずに戻っても)問題ない
689 */
690 bx lr /* 実行再開番地を復帰 */
691
692ALABEL(idle_loop)
693 /*
694 * 割込みを許可したらCPUロック解除状æ…
695‹ã«ãªã‚‹ã‚ˆã†æº–備する
696 * CPUロック状æ…
697‹ã®è§£é™¤ã¨ï¼Œéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆå®Ÿè¡ŒçŠ¶æ…
698‹ã¸ã®
699 * 準備をする
700 */
701 /*
702 * pspにダミーフレームを積んでbx lrにより,threadモードかつidleへ
703 * この時点では,r3=pspである
704 * r3には,dispatchでcallee-saved-registerが保存されたあとの
705 * スタックポインタがå…
706¥ã£ã¦ãŠã‚Šï¼Œãã®ç¶šãã‹ã‚‰ã‚¹ã‚¿ãƒƒã‚¯ã‚’使用する
707 */
708 ldr r0, =_idle_loop /* PC */
709 ldr r1, =EPSR_T /* xPSR(Tビットが'1'である必
710要がある) */
711 /*
712 * アイドルループ中のFPは任意なので設定しない
713 */
714 ldr lr, =0xfffffffd
715 stmfd r3!, {r0-r1} /* ダミーフレームをスタック上に積む */
716 sub r3, #(6*4) /* r0-r3,r12,lrの内
717容は設定する必
718要がない */
719 msr psp, r3
720 bx lr
721
722ALABEL(_idle_loop)
723 /* ここではすでに割込み許可状æ…
724‹ */
725#ifdef TOPPERS_CUSTOM_IDLE
726 toppers_asm_custom_idle
727#else
728ALABEL(_idle_loop_1)
729 /*
730 * basepriをå…
731¨å‰²è¾¼ã¿è¨±å¯ã«è¨­å®šã—てからwfiが発行されるまでに
732 * 割込みがå…
733¥ã£ãŸå ´åˆï¼Œãã“でディスパッチが必
734要な状æ…
735‹ã«ãªã‚Œã°
736 * 割込みの出口処理で遅
737延ディスパッチし,ここには戻ってこない.
738 * 遅
739延ディスパッチしなかった場合はここに戻ってきて次の割込みを
740 * wfiで待
741つため,想定どおりの動作となる
742 */
743 wfi
744 b _idle_loop_1
745 nop
746#endif /* TOPPERS_CUSTOM_IDLE */
747
748/*
749 * カーネルの終了処理の呼出し
750 *
751 * スタックを非タスクコンテキスト用に切り替え.
752 *
753 */
754 ATHUMB(call_exit_kernel)
755 AGLOBAL(call_exit_kernel)
756ALABEL(call_exit_kernel)
757 mov r0, #CONTROL_MSP
758 msr control, r0 /* MSPを有効に */
759 isb /* control の操作後に必
760要 */
761 ldr r0, =exit_kernel /* カーネルの終了処理を呼ぶ */
762 bx r0
763
764/*
765 * 微少時間待
766ち
767 */
768 AALIGN(2)
769 ATEXT
770 ATHUMB(sil_dly_nse)
771 AGLOBAL(sil_dly_nse)
772ALABEL(sil_dly_nse)
773 sub r0, r0, #SIL_DLY_TIM1
774 cmp r0, #0
775 bgt sil_dly_nse1
776 bx lr
777ALABEL(sil_dly_nse1)
778 sub r0, r0, #SIL_DLY_TIM2
779 cmp r0, #0
780 bgt sil_dly_nse1
781 bx lr
782
Note: See TracBrowser for help on using the repository browser.