source: rtos_arduino/trunk/asp_1.9.2/arch/arm_m_gcc/common/core_support_v6m.S@ 136

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

ライブラリとOS及びベーシックなサンプルの追加.

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