source: asp3_wo_tecs/trunk/arch/arm_gcc/common/core_support.S@ 306

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

3.1.0を反映

File size: 34.3 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-2004 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2006-2016 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 733 2016-04-03 09:10:54Z ertl-hiro $
56 */
57
58/*
59 * カーネルのコア依存部のアセンブリ言語部(ARM用)
60 */
61
62#define TOPPERS_MACRO_ONLY
63#define TOPPERS_ASM_MACRO
64#define UINT_C(val) (val) /* uint_t型の定数を作るマクロ */
65#define ULONG_C(val) (val) /* ulong_t型の定数を作るマクロ */
66#define CAST(type, val) (val) /* 型キャストを行うマクロ */
67#include "kernel_impl.h"
68#include "offset.h"
69#include "core_asm.inc"
70
71/*
72 * 例外ベクタ
73 */
74 ASECTION(.vector)
75 AALIGN(5)
76 AGLOBAL(vector_table)
77ALABEL(vector_table)
78 ldr pc, reset_vector /* リセット */
79 ldr pc, undef_vector /* 未定義命令 */
80 ldr pc, svc_vector /* ソフトウェア割込み */
81 ldr pc, pabort_vector /* プリフェッチアボート */
82 ldr pc, dabort_vector /* データアボート */
83 ldr pc, reset_vector /* 未使用 */
84 ldr pc, irq_vector /* IRQ */
85 ldr pc, fiq_vector /* FIQ */
86
87/*
88 * 例外ベクタの命令から参ç…
89§ã•ã‚Œã‚‹ã‚¸ãƒ£ãƒ³ãƒ—å…
90ˆã‚¢ãƒ‰ãƒ¬ã‚¹
91 */
92 AGLOBAL(vector_ref_table)
93ALABEL(vector_ref_table)
94ALABEL(reset_vector)
95 ALONG start
96ALABEL(undef_vector)
97 ALONG undef_handler
98ALABEL(svc_vector)
99 ALONG svc_handler
100ALABEL(pabort_vector)
101 ALONG pabort_handler
102ALABEL(dabort_vector)
103 ALONG dabort_handler
104ALABEL(irq_vector)
105 ALONG irq_handler
106ALABEL(fiq_vector)
107 ALONG fiq_handler
108
109/*
110 * タスクディスパッチャ
111 */
112 ATEXT
113 AALIGN(2)
114 AGLOBAL(dispatch)
115ALABEL(dispatch)
116 /*
117 * このルーチンは,タスクコンテキスト・CPUロック状æ…
118‹ãƒ»å‰²è¾¼ã¿å„ªå…
119ˆåº¦
120 * マスクå…
121¨è§£é™¤çŠ¶æ…
122‹ãƒ»ãƒ‡ã‚£ã‚¹ãƒ‘ッチ許可状æ…
123‹ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Ž
124 */
125 push {r12,lr} /* 戻り番地を保存,r12はダミー */
126#ifdef TOPPERS_SUPPORT_OVRHDR
127 bl ovrtimer_stop
128#endif /* TOPPERS_SUPPORT_OVRHDR */
129 stmfd sp!, {r4-r11} /* 非スクラッチレジスタの保存 */
130 ldr r0, =p_runtsk /* p_runtsk → r0 */
131 ldr r0, [r0]
132 str sp, [r0,#TCB_sp] /* スタックポインタを保存 */
133 adr r1, dispatch_r
134 str r1, [r0,#TCB_pc] /* 実行再開番地を保存 */
135 b dispatcher /* r0にはp_runtskが格納されている */
136
137ALABEL(dispatch_r)
138 ldmfd sp!, {r4-r11} /* 非スクラッチレジスタの復帰 */
139#ifdef TOPPERS_SUPPORT_OVRHDR
140 bl ovrtimer_start
141#endif /* TOPPERS_SUPPORT_OVRHDR */
142 pop {r12,lr} /* 戻り番地を復帰 */
143 bx lr
144
145/*
146 * ディスパッチャの動作開始
147 */
148 AGLOBAL(start_dispatch)
149ALABEL(start_dispatch)
150 /*
151 * このルーチンは,カーネル起動時に,非タスクコンテキストで,NMIを
152 * 除くすべての割込みを禁止した状æ…
153‹ï¼ˆå…
154¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
155‹ã¨åŒç­‰ï¼‰ã§
156 * 呼び出される.
157 *
158 * dispatcher_0へ分岐する前に,タスクコンテキスト・CPUロック状æ…
159‹ãƒ»
160 * 割込み優å…
161ˆåº¦ãƒžã‚¹ã‚¯å…
162¨è§£é™¤çŠ¶æ…
163‹ã«ã—,使用するスタックを,IDが1のタ
164 * スクのスタック領域に切り換えなければならない.
165 */
166
167 /*
168 * タスクコンテキストに切り換える.
169 */
170 ldr r2, =excpt_nest_count /* 例外ネストカウントを0に */
171 mov r0, #0
172 str r0, [r2]
173
174 /*
175 * IDが1のタスクのスタック領域に切り換える.
176 */
177 ldr r0, =tcb_table /* tcb_table[0] → r0 */
178 ldr r2, [r0,#TCB_p_tinib] /* tcb_table[0].p_tinib → r2 */
179 ldr r0, [r2,#TINIB_stk]
180 ldr r1, [r2,#TINIB_stksz]
181 add sp, r0, r1
182
183 /*
184 * CPUロック状æ…
185‹ã«ã—て,ディスパッチャ本体へ分岐する.
186 */
187 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_CPULOCK)
188 b dispatcher_0
189
190/*
191 * 現在のコンテキストを捨ててディスパッチ
192 */
193 AGLOBAL(exit_and_dispatch)
194ALABEL(exit_and_dispatch)
195 /*
196 * このルーチンは,タスクコンテキスト・CPUロック状æ…
197‹ãƒ»å‰²è¾¼ã¿å„ªå…
198ˆåº¦
199 * マスクå…
200¨è§£é™¤çŠ¶æ…
201‹ãƒ»ãƒ‡ã‚£ã‚¹ãƒ‘ッチ許可状æ…
202‹ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Ž
203 */
204#ifdef LOG_DSP_ENTER
205 ldr r0, =p_runtsk /* p_runtsk → r0 */
206 ldr r0, [r0]
207#endif /* LOG_DSP_ENTER */
208 /* ディスパッチャ本体(dispatcher)へ */
209
210/*
211 * ディスパッチャ本体
212 */
213ALABEL(dispatcher)
214#ifdef LOG_DSP_ENTER
215 /*
216 * 【この時点のレジスタ状æ…
217‹ã€‘
218 * r0:p_runtsk(タスク切換え前)
219 */
220 bl log_dsp_enter
221#endif /* LOG_DSP_ENTER */
222
223ALABEL(dispatcher_0)
224 /*
225 * このルーチンは,タスクコンテキスト・CPUロック状æ…
226‹ãƒ»å‰²è¾¼ã¿å„ªå…
227ˆåº¦
228 * マスクå…
229¨è§£é™¤çŠ¶æ…
230‹ãƒ»ãƒ‡ã‚£ã‚¹ãƒ‘ッチ許可状æ…
231‹ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Žå®Ÿè¡Œå†é–‹ç•ª
232 * 地へもこの状æ…
233‹ã®ã¾ã¾åˆ†å²ã™ã‚‹ï¼Ž
234 */
235 ldr r0, =p_schedtsk /* p_schedtsk → r4 → p_runtsk */
236 ldr r4, [r0]
237 ldr r1, =p_runtsk
238 str r4, [r1]
239 tst r4, r4 /* p_runtskがNULLならdispatcher_1へ */
240 beq dispatcher_1
241 ldr sp, [r4,#TCB_sp] /* タスクスタックを復帰 */
242#ifdef LOG_DSP_LEAVE
243 mov r0, r4 /* p_runtskをパラメータに渡す */
244 bl log_dsp_leave
245#endif /* LOG_DSP_LEAVE */
246 ldr r0, [r4,#TCB_pc] /* 実行再開番地を復帰 */
247 bx r0 /* p_runtskをr4にå…
248¥ã‚ŒãŸçŠ¶æ…
249‹ã§åˆ†å²ã™ã‚‹ */
250
251 /*
252 * アイドル処理
253 *
254 * 割込みをすべて許可し,CPUロック解除状æ…
255‹ã«ã—て割込みを待
256つ.
257 *
258 * ターゲットによっては,省電力モード等に移行するため,標準の方法
259 * と異なる手順が必
260要な場合がある.そのようなターゲットでは,ター
261 * ゲット依存部でTOPPERS_CUSTOM_IDLEを定義し,アセンブラマクロとし
262 * て,toppers_asm_custom_idleを用意すればよい.
263 */
264ALABEL(dispatcher_1)
265#ifdef TOPPERS_CUSTOM_IDLE
266 toppers_asm_custom_idle
267#else /* TOPPERS_CUSTOM_IDLE */
268 msr cpsr_c, #CPSR_SVC_MODE /* 割込みを許可(スーパバイザモード)*/
269ALABEL(dispatcher_2)
270 b dispatcher_2 /* 割込み待
271ち */
272#endif /* TOPPERS_CUSTOM_IDLE */
273
274/*
275 * カーネルの終了処理の呼出し
276 *
277 * 割込みロック状æ…
278‹ã«ã—,使用するスタックを非タスクコンテキスト用のスタッ
279 * ク領域に切り替え,exit_kernelを呼び出す.
280 */
281 AGLOBAL(call_exit_kernel)
282ALABEL(call_exit_kernel)
283 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_INTLOCK)
284 ldr r0, =istkpt /* 非タスクコンテキストのスタックへ */
285 ldr sp, [r0]
286 b exit_kernel
287
288/*
289 * タスクの実行開始時処理
290 */
291 ATEXT
292 AALIGN(2)
293 AGLOBAL(start_r)
294 /*
295 * ディスパッチャ本体から呼び出されるため,p_runtskはr4にå…
296¥ã£ã¦ã„る.
297 */
298ALABEL(start_r)
299#ifdef TOPPERS_SUPPORT_OVRHDR
300 bl ovrtimer_start
301#endif /* TOPPERS_SUPPORT_OVRHDR */
302 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_UNLOCK)
303 /* CPUロック解除状æ…
304‹ã« */
305 ldr lr, =ext_tsk /* タスク本体からの戻り番地を設定 */
306 ldr r2, [r4,#TCB_p_tinib] /* p_runtsk->p_tinib → r2 */
307 ldr r0, [r2,#TINIB_exinf] /* exinfをパラメータに */
308 ldr r1, [r2,#TINIB_task] /* タスク起動番地にジャンプ */
309 bx r1
310
311/*
312 * 割込みハンドラの出å…
313¥å£å‡¦ç†
314 */
315#ifndef OMIT_IRQ_HANDLER
316 ATEXT
317 AALIGN(2)
318 AGLOBAL(irq_handler)
319ALABEL(irq_handler)
320 /*
321 * ここには,IRQモードで分岐してくる.
322 */
323#if __TARGET_ARCH_ARM < 6
324 /*
325 * スーパバイザモードに切り換え,スクラッチレジスタを保存する.
326 */
327 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_IRQ_BIT)
328 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */
329
330 /*
331 * IRQモードに戻して,戻り番地とspsr(戻りå…
332ˆã®cpsr)を取得する.
333 */
334 msr cpsr_c, #(CPSR_IRQ_MODE AOR CPSR_IRQ_BIT)
335 sub r2, lr, #4
336 mrs r1, spsr
337
338 /*
339 * スーパバイザモードに切り換え,戻り番地とspsrを保存する.
340 */
341 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_IRQ_BIT)
342 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 */
343 push {r1} /* spsrをスタックに保存 */
344#else /* __TARGET_ARCH_ARM < 6 */
345 /*
346 * 戻りå…
347ˆï¼ˆlr)とspsr(cpsr_svc)をスーパバイザモードのスタックに
348 * 保存する.
349 */
350 sub lr, lr, #4 /* 戻り番地の算出 */
351 srsfd #CPSR_SVC_MODE!
352
353 /*
354 * スーパバイザモードに切り換え,スクラッチレジスタを保存する.
355 */
356 cps #CPSR_SVC_MODE
357 stmfd sp!, {r0-r5,r12,lr}
358#endif /* __TARGET_ARCH_ARM < 6 */
359
360 /*
361 * スタックポインタの調整
362 */
363 and r1, sp, #4
364 sub sp, sp, r1
365 push {r0,r1} /* r0はスペース確保のため */
366
367 /*
368 * 例外ネストカウントをインクリメントする.割込みが非タスクコンテキ
369 * ストで発生した場合には,irq_handler_1へ分岐する.
370 */
371 ldr r2, =excpt_nest_count
372 ldr r3, [r2]
373 add r3, r3, #1
374 str r3, [r2]
375 teq r3, #1 /* 割込みが非タスクコンテキストで発生 */
376 bne irq_handler_1 /* ならirq_handler_1に分岐 */
377
378#ifdef TOPPERS_SUPPORT_OVRHDR
379 /*
380 * オーバランタイマを停止する.
381 */
382 bl ovrtimer_stop
383#endif /* TOPPERS_SUPPORT_OVRHDR */
384
385 /*
386 * 非タスクコンテキスト用のスタックに切り換える.
387 */
388 mov r3, sp /* この時点のスタックポインタをr3に */
389 ldr r2, =istkpt /* 非タスクコンテキスト用のスタックに */
390 ldr sp, [r2]
391 push {r0,r3} /* 切換え前のスタックポインタを保存 */
392 /* r0はスペース確保のため */
393ALABEL(irq_handler_1)
394 /*
395 * 割込みコントローラを操作し,割込み番号を取得する.
396 */
397 bl irc_begin_int
398#if TNUM_INHNO <= 256 || __TARGET_ARCH_ARM <= 6
399 cmp r4, #TNUM_INHNO /* TNUM_INHNOの値によってはエラーになる */
400#else /* TNUM_INHNO <= 256 || __TARGET_ARCH_ARM <= 6 */
401 movw r3, #TNUM_INHNO
402 cmp r4, r3
403#endif /* TNUM_INHNO <= 256 || __TARGET_ARCH_ARM <= 6 */
404 bhs irq_handler_2 /* スプリアス割込みなら */
405 /* irq_handler_2に分岐 */
406 /*
407 * CPUロック解除状æ…
408‹ã«ã™ã‚‹ï¼Ž
409 */
410#if __TARGET_ARCH_ARM < 6
411 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_UNLOCK)
412#else /* __TARGET_ARCH_ARM < 6 */
413#ifndef TOPPERS_SAFEG_SECURE
414 cpsie if
415#else /* TOPPERS_SAFEG_SECURE */
416 cpsie f
417#endif /* TOPPERS_SAFEG_SECURE */
418#endif /* __TARGET_ARCH_ARM < 6 */
419
420#ifdef LOG_INH_ENTER
421 /*
422 * ログ出力の呼出し
423 */
424 mov r0, r4 /* 割込み番号をパラメータに渡す */
425 bl log_inh_enter
426#endif /* LOG_INH_ENTER */
427
428 /*
429 * 割込みハンドラの呼出し
430 */
431 ldr r2, =inh_table /* 割込みハンドラテーブルの読込み */
432 ldr r1, [r2,r4,lsl #2] /* 割込みハンドラの番地 → r1 */
433 mov lr, pc /* 割込みハンドラの呼出し */
434 bx r1
435
436#ifdef LOG_INH_LEAVE
437 /*
438 * ログ出力の呼出し
439 */
440 mov r0, r4 /* 割込み番号をパラメータに渡す */
441 bl log_inh_leave
442#endif /* LOG_INH_LEAVE */
443
444 /*
445 * カーネル管理の割込みを禁止する.
446 */
447#if __TARGET_ARCH_ARM < 6
448 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_CPULOCK)
449#else /* __TARGET_ARCH_ARM < 6 */
450#ifndef TOPPERS_SAFEG_SECURE
451 cpsid i
452#else /* TOPPERS_SAFEG_SECURE */
453 cpsid if
454#endif /* TOPPERS_SAFEG_SECURE */
455#endif /* __TARGET_ARCH_ARM < 6 */
456
457 /*
458 * 割込みコントローラを操作する.
459 */
460ALABEL(irq_handler_2)
461 bl irc_end_int
462
463 /*
464 * 例外ネストカウントをデクリメントする.
465 */
466 ldr r2, =excpt_nest_count
467 ldr r3, [r2]
468 subs r3, r3, #1
469 str r3, [r2] /* 戻りå…
470ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãªã‚‰ */
471 bne irq_handler_3 /* irq_handler_3に分岐 */
472
473 /*
474 * タスク用のスタックに戻す.
475 */
476 pop {r0,r3}
477 mov sp, r3
478
479 /*
480 * ディスパッチが必
481要か判定する.
482 */
483 ldr r0, =p_runtsk /* p_runtsk → r0 */
484 ldr r0, [r0]
485 ldr r1, =p_schedtsk /* p_schedtsk → r1 */
486 ldr r1, [r1]
487 teq r0, r1 /* p_runtskとp_schedtskが同じなら */
488 beq irq_handler_4 /* irq_handler_4へ */
489
490 /*
491 * コンテキストを保存する.
492 */
493 tst r0, r0 /* p_runtskがNULLならdispatcher_0へ */
494 beq dispatcher_0
495 stmfd sp!, {r6-r11} /* 非スクラッチレジスタの保存 */
496 str sp, [r0,#TCB_sp] /* スタックポインタを保存 */
497 adr r1, ret_int_r /* 実行再開番地を保存 */
498 str r1, [r0,#TCB_pc]
499 b dispatcher /* r0にはp_runtskが格納されている */
500
501ALABEL(ret_int_r)
502 /*
503 * コンテキストを復帰する.
504 */
505 ldmfd sp!, {r6-r11} /* 非スクラッチレジスタの復帰 */
506
507#ifdef TOPPERS_SUPPORT_OVRHDR
508 /*
509 * オーバランタイマを動作開始する.
510 */
511 bl ovrtimer_start
512#endif /* TOPPERS_SUPPORT_OVRHDR */
513
514 /*
515 * 割込み/CPU例外処理からのリターン
516 *
517 * 割込み/CPU例外処理からのリターンにより,CPUロック解除状æ…
518‹ã«é·
519 * 移するようにする必
520要があるが,ARMはCPSRのビットによってCPUロッ
521 * ク状æ…
522‹ã‚’表しているため,CPSRをå…
523ƒã«æˆ»ã—てリターンすればよい.
524 */
525#ifndef TOPPERS_SUPPORT_OVRHDR
526ALABEL(irq_handler_4)
527#endif /* TOPPERS_SUPPORT_OVRHDR */
528ALABEL(irq_handler_3)
529 pop {r0,r1} /* スタックポインタの調整 */
530 add sp, sp, r1
531#if __TARGET_ARCH_ARM < 6
532 ldmfd sp!, {r0} /* 戻りå…
533ˆã®cpsrをspsrに設定 */
534 msr spsr_cxsf, r0
535 ldmfd sp!, {r0-r5,r12,lr,pc}^ /* コンテキストの復帰 */
536 /* ^付きなので,spsr → cpsr */
537#else /* __TARGET_ARCH_ARM < 6 */
538 ldmfd sp!, {r0-r5,r12,lr}
539 rfefd sp!
540#endif /* __TARGET_ARCH_ARM < 6 */
541
542#ifdef TOPPERS_SUPPORT_OVRHDR
543ALABEL(irq_handler_4)
544 /*
545 * オーバランタイマを動作開始する.
546 */
547 tst r0, r0 /* p_runtskがNULLでない場合 */
548 blne ovrtimer_start
549 b irq_handler_3
550#endif /* TOPPERS_SUPPORT_OVRHDR */
551#endif /* OMIT_IRQ_HANDLER */
552
553/*
554 * CPU例外ハンドラ出å…
555¥å£å‡¦ç†
556 */
557ALABEL(start_exc_entry)
558
559/*
560 * 未定義命令
561 */
562#ifndef OMIT_UNDEF_HANDLER
563 ATEXT
564 AALIGN(2)
565 AGLOBAL(undef_handler)
566ALABEL(undef_handler)
567 /*
568 * ここには,未定義モードで分岐してくる.
569 */
570#if __TARGET_ARCH_ARM < 6
571 /*
572 * IビットとFビットをセットし,スーパバイザモードに切り換え,スク
573 * ラッチレジスタを保存する.
574 */
575 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
576 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */
577
578 /*
579 * 未定義モードに戻して,戻り番地とspsrを取得する.
580 */
581 msr cpsr_c, #(CPSR_UND_MODE AOR CPSR_FIQ_IRQ_BIT)
582 mov r2, lr
583 mrs r1, spsr
584
585 /*
586 * スーパバイザモードに切り換え,戻り番地とspsrを保存する.
587 */
588 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
589 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 */
590 push {r1} /* spsrをスタックに保存 */
591#else /* __TARGET_ARCH_ARM < 6 */
592 /*
593 * 戻りå…
594ˆï¼ˆlr)とspsr(cpsr_svc)をスーパバイザモードのスタックに
595 * 保存する.
596 */
597 srsfd #CPSR_SVC_MODE!
598
599 /*
600 * スーパバイザモードに切り換え,スクラッチレジスタを保存する.
601 */
602 cps #CPSR_SVC_MODE
603 stmfd sp!, {r0-r5,r12,lr}
604#endif /* __TARGET_ARCH_ARM < 6 */
605 mov r4, #EXCNO_UNDEF
606 b exc_handler_1
607#endif /* OMIT_UNDEF_HANDLER */
608
609/*
610 * スーパバイザコール
611 */
612#ifndef OMIT_SVC_HANDLER
613 ATEXT
614 AALIGN(2)
615 AGLOBAL(svc_handler)
616ALABEL(svc_handler)
617 /*
618 * ここには,スーパバイザモードで分岐してくる.
619 */
620#if __TARGET_ARCH_ARM < 6
621 /*
622 * IビットとFビットをセットし,スクラッチレジスタを保存する.
623 */
624 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
625 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */
626
627 /*
628 * 戻り番地とspsrを取得する.
629 */
630 mov r2, lr
631 mrs r1, spsr
632
633 /*
634 * 戻り番地とspsrを保存する.
635 */
636 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 */
637 push {r1} /* spsrをスタックに保存 */
638#else /* __TARGET_ARCH_ARM < 6 */
639 /*
640 * 戻りå…
641ˆï¼ˆlr)とspsr(cpsr_svc)をスーパバイザモードのスタックに
642 * 保存する.
643 */
644 srsfd #CPSR_SVC_MODE!
645
646 /*
647 * スーパバイザモードで,スクラッチレジスタを保存する.
648 */
649 cps #CPSR_SVC_MODE /* 不要と思われる */
650 stmfd sp!, {r0-r5,r12,lr}
651#endif /* __TARGET_ARCH_ARM < 6 */
652 mov r4, #EXCNO_SVC
653 b exc_handler_1
654#endif /* OMIT_SVC_HANDLER */
655
656/*
657 * プリフェッチアボート
658 */
659#ifndef OMIT_PABORT_HANDLER
660 ATEXT
661 AALIGN(2)
662 AGLOBAL(pabort_handler)
663ALABEL(pabort_handler)
664 /*
665 * ここには,アボートモードで分岐してくる.
666 */
667#if __TARGET_ARCH_ARM < 6
668 /*
669 * IビットとFビットをセットし,スーパバイザモードに切り換え,スク
670 * ラッチレジスタを保存する.
671 */
672 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
673 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */
674
675 /*
676 * アボートモードに戻して,戻り番地とspsrを取得する.
677 */
678 msr cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT)
679 mov r2, lr
680 mrs r1, spsr
681
682 /*
683 * スーパバイザモードに切り換え,戻り番地とspsrを保存する.
684 */
685 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
686 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 */
687 push {r1} /* spsrをスタックに保存 */
688#else /* __TARGET_ARCH_ARM < 6 */
689 /*
690 * 戻りå…
691ˆï¼ˆlr)とspsr(cpsr_svc)をスーパバイザモードのスタックに
692 * 保存する.
693 */
694 srsfd #CPSR_SVC_MODE!
695
696 /*
697 * スーパバイザモードに切り換え,スクラッチレジスタを保存する.
698 */
699 cps #CPSR_SVC_MODE
700 stmfd sp!, {r0-r5,r12,lr}
701#endif /* __TARGET_ARCH_ARM < 6 */
702 mov r4, #EXCNO_PABORT
703 b exc_handler_1
704#endif /* OMIT_PABORT_HANDLER */
705
706/*
707 * データアボート
708 */
709#ifndef OMIT_DABORT_HANDLER
710 ATEXT
711 AALIGN(2)
712 AGLOBAL(dabort_handler)
713ALABEL(dabort_handler)
714 /*
715 * ここには,アボートモードで分岐してくる.
716 *
717 * データアボートが,CPU例外のå…
718¥å£ï¼ˆstart_exc_entryとend_exc_entry
719 * の間)で発生した場合には,fatal_dabort_handlerに分岐する.アボー
720 * トモードのspを汎用レジスタの代わりに使用する.
721 */
722 ldr sp, =start_exc_entry+8
723 cmp lr, sp
724 bcc dabort_handler_1
725 ldr sp, =end_exc_entry+8
726 cmp lr, sp
727 bcc fatal_dabort_handler
728
729ALABEL(dabort_handler_1)
730#if __TARGET_ARCH_ARM < 6
731 /*
732 * IビットとFビットをセットし,スーパバイザモードに切り換え,スク
733 * ラッチレジスタを保存する.
734 */
735 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
736 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */
737
738 /*
739 * アボートモードに戻して,戻り番地とspsrを取得する.
740 */
741 msr cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT)
742 mov r2, lr
743 mrs r1, spsr
744
745 /*
746 * スーパバイザモードに切り換え,戻り番地とspsrを保存する.
747 */
748 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
749 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 */
750 push {r1} /* spsrをスタックに保存 */
751#else /* __TARGET_ARCH_ARM < 6 */
752 /*
753 * 戻りå…
754ˆï¼ˆlr)とspsr(cpsr_svc)をスーパバイザモードのスタックに
755 * 保存する.
756 */
757 srsfd #CPSR_SVC_MODE!
758
759 /*
760 * スーパバイザモードに切り換え,スクラッチレジスタを保存する.
761 */
762 cps #CPSR_SVC_MODE
763 stmfd sp!, {r0-r5,r12,lr}
764#endif /* __TARGET_ARCH_ARM < 6 */
765 mov r4, #EXCNO_DABORT
766 b exc_handler_1
767#endif /* OMIT_DABORT_HANDLER */
768
769/*
770 * CPU例外のå…
771¥å£ã§ç™ºç”Ÿã—たデータアボート
772 */
773ALABEL(fatal_dabort_handler)
774#if __TARGET_ARCH_ARM < 6
775 /*
776 * IビットとFビットをセットし,スーパバイザモードに切り換え,スタッ
777 * クポインタを初期化し,スクラッチレジスタを保存する.
778 */
779 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
780 ldr sp, =istkpt
781 ldr sp, [sp]
782 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */
783
784 /*
785 * アボートモードに戻して,戻り番地とspsrを取得する.
786 */
787 msr cpsr_c, #(CPSR_ABT_MODE AOR CPSR_FIQ_IRQ_BIT)
788 mov r2, lr
789 mrs r1, spsr
790
791 /*
792 * スーパバイザモードに切り換え,戻り番地とspsrを保存する.
793 */
794 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
795 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 */
796 push {r1} /* spsrをスタックに保存 */
797#else /* __TARGET_ARCH_ARM < 6 */
798 /*
799 * IビットとFビットをセットし,スーパバイザモードに切り換え,スタッ
800 * クポインタを初期化する.
801 */
802 cpsid if, #CPSR_SVC_MODE
803 ldr sp, =istkpt
804 ldr sp, [sp]
805
806 /*
807 * アボートモードに戻して,戻りå…
808ˆï¼ˆlr)とspsr(cpsr_svc)をスーパ
809 * バイザモードのスタックに保存する.
810 */
811 cps #CPSR_ABT_MODE
812 srsfd #CPSR_SVC_MODE!
813
814 /*
815 * スーパバイザモードに切り換え,スクラッチレジスタを保存する.
816 */
817 cps #CPSR_SVC_MODE
818 stmfd sp!, {r0-r5,r12,lr}
819#endif /* __TARGET_ARCH_ARM < 6 */
820
821 /*
822 * 例外ネストカウントの最上位ビットを1にする.
823 */
824 ldr r2, =excpt_nest_count
825 ldr r3, [r2]
826 orr r3, r3, #0x80000000
827 str r3, [r2]
828
829 mov r4, #EXCNO_DABORT
830 b exc_handler_1
831
832/*
833 * FIQ
834 */
835#ifndef OMIT_FIQ_HANDLER
836 ATEXT
837 AALIGN(2)
838 AGLOBAL(fiq_handler)
839ALABEL(fiq_handler)
840 /*
841 * ここには,FIQモードで分岐してくる.
842 */
843#if __TARGET_ARCH_ARM < 6
844 /*
845 * IビットとFビットをセットし,スーパバイザモードに切り換え,スク
846 * ラッチレジスタを保存する.
847 */
848 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
849 stmfd sp!, {r0-r5,r12,lr,pc} /* pcはスペース確保のため */
850
851 /*
852 * FIQモードに戻して,戻り番地とspsrを取得する.
853 */
854 msr cpsr_c, #(CPSR_FIQ_MODE AOR CPSR_FIQ_IRQ_BIT)
855 mov r2, lr
856 mrs r1, spsr
857
858 /*
859 * スーパバイザモードに切り換え,戻り番地とspsrを保存する.
860 */
861 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_FIQ_IRQ_BIT)
862 str r2, [sp,#0x20] /* 戻り番地をスタックに保存 */
863 push {r1} /* spsrをスタックに保存 */
864#else /* __TARGET_ARCH_ARM < 6 */
865 /*
866 * 戻りå…
867ˆï¼ˆlr)とspsr(cpsr_svc)をスーパバイザモードのスタックに
868 * 保存する.
869 */
870 srsfd #CPSR_SVC_MODE!
871
872 /*
873 * スーパバイザモードに切り換え,スクラッチレジスタを保存する.
874 */
875 cps #CPSR_SVC_MODE
876 stmfd sp!, {r0-r5,r12,lr}
877#endif /* __TARGET_ARCH_ARM < 6 */
878 mov r4, #EXCNO_FIQ
879 b exc_handler_1
880#endif /* OMIT_FIQ_HANDLER */
881
882ALABEL(end_exc_entry)
883
884/*
885 * CPU例外ハンドラ出å…
886¥å£å‡¦ç†ã®å…
887±é€šéƒ¨åˆ†
888 *
889 * 【この時点のレジスタ状æ…
890‹ã€‘
891 * r4:CPU例外ハンドラ番号
892 */
893ALABEL(exc_handler_1)
894 /*
895 * CPU例外が発生した状況の判断に用いるために,CPU例外発生前の割
896 * 込み優å…
897ˆåº¦ãƒžã‚¹ã‚¯ã¨ä¾‹å¤–ネストカウントをスタックに保存する.
898 */
899 bl irc_get_intpri
900 push {r0} /* 割込み優å…
901ˆåº¦ãƒžã‚¹ã‚¯ã‚’保存 */
902 ldr r2, =excpt_nest_count
903 ldr r3, [r2]
904 push {r3} /* 例外ネストカウントを保存 */
905 mov r5, sp /* CPU例外の情
906報を記憶している領域の */
907 /* å…
908ˆé ­ç•ªåœ°ã‚’r5に保存 */
909 /*
910 * スタックポインタの調整
911 */
912 and r1, sp, #4
913 sub sp, sp, r1
914 push {r0,r1} /* r0はスペース確保のため */
915
916 /*
917 * カーネル管理外のCPU例外か判定する
918 *
919 * カーネル管理外のCPU例外は,カーネル実行中,å…
920¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
921‹ï¼Œ
922 * CPUロック状æ…
923‹ï¼Œã‚«ãƒ¼ãƒãƒ«ç®¡ç†å¤–の割込みハンドラ実行中に発生した
924 * CPU例外である.ARMコアの場合は,戻りå…
925ˆã®CPSRのIビットかFビット
926 * のいずれかがセットされているなら,これ該当する.
927 */
928 ldr r1, [r5,#T_EXCINF_cpsr] /* 例外フレームからcpsrを取得 */
929 ands r1, r1, #CPSR_FIQ_IRQ_BIT
930 bne nk_exc_handler_1 /* カーネル管理外のCPU例外の処理へ */
931
932 /*
933 * 【この時点のレジスタ状æ…
934‹ã€‘
935 * r2:excpt_nest_countの番地
936 * r3:excpt_nest_countの値
937 * r4:CPU例外ハンドラ番号
938 * r5:CPU例外の情
939報を記憶している領域のå…
940ˆé ­ç•ªåœ°
941 */
942
943 /*
944 * 例外ネストカウントをインクリメントする.
945 */
946 add r3, r3, #1
947 str r3, [r2]
948 teq r3, #1 /* CPU例外発生前が非タスクコンテキスト */
949 bne exc_handler_2 /* ならexc_handler_2に分岐 */
950
951#ifdef TOPPERS_SUPPORT_OVRHDR
952 /*
953 * オーバランタイマを停止する.
954 */
955 bl ovrtimer_stop
956#endif /* TOPPERS_SUPPORT_OVRHDR */
957
958 /*
959 * 非タスクコンテキスト用のスタックに切り換える.
960 */
961 mov r3, sp /* この時点のスタックポインタをr3に */
962 ldr r2, =istkpt /* 非タスクコンテキスト用のスタックに */
963 ldr sp, [r2]
964 push {r0,r3} /* 切換え前のスタックポインタを保存 */
965 /* r0はスペース確保のため */
966ALABEL(exc_handler_2)
967 /*
968 * 【この時点のレジスタ状æ…
969‹ã€‘
970 * r4:CPU例外ハンドラ番号
971 * r5:CPU例外の情
972報を記憶している領域のå…
973ˆé ­ç•ªåœ°
974 */
975
976 /*
977 * (必
978要なら)割込みコントローラを操作する.
979 */
980 bl irc_begin_exc
981
982 /*
983 * CPUロック解除状æ…
984‹ã«ã™ã‚‹ï¼Ž
985 *
986 * カーネル管理外のCPU例外ハンドラは別ルーチンで呼び出すため,単純
987 * に割込みを許可するだけでよい.
988 */
989#if __TARGET_ARCH_ARM < 6
990 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_UNLOCK)
991#else /* __TARGET_ARCH_ARM < 6 */
992#ifndef TOPPERS_SAFEG_SECURE
993 cpsie if
994#else /* TOPPERS_SAFEG_SECURE */
995 cpsie f
996#endif /* TOPPERS_SAFEG_SECURE */
997#endif /* __TARGET_ARCH_ARM < 6 */
998
999 /*
1000 * ログ出力の呼出し
1001 */
1002#ifdef LOG_EXC_ENTER
1003 mov r0, r4 /* CPU例外番号をパラメータに渡す */
1004 bl log_exc_enter
1005#endif /* LOG_EXC_ENTER */
1006
1007 /*
1008 * CPU例外ハンドラの呼出し
1009 */
1010 ldr r2, =exc_table /* CPU例外ハンドラテーブルの読込み */
1011 ldr r3, [r2,r4,lsl #2] /* CPU例外ハンドラの番地 → r3 */
1012 mov r0, r5 /* CPU例外の情
1013報を記憶している領域の */
1014 /* å…
1015ˆé ­ç•ªåœ°ã‚’第1パラメータに渡す */
1016 mov r1, r4 /* CPU例外番号を第2パラメータに渡す */
1017 mov lr, pc /* CPU例外ハンドラの呼出し */
1018 bx r3
1019
1020 /*
1021 * ログ出力の呼出し
1022 */
1023#ifdef LOG_EXC_LEAVE
1024 mov r0, r4 /* CPU例外番号をパラメータに渡す */
1025 bl log_exc_leave
1026#endif /* LOG_EXC_LEAVE */
1027
1028 /*
1029 * カーネル管理の割込みを禁止する.
1030 */
1031#if __TARGET_ARCH_ARM < 6
1032 msr cpsr_c, #(CPSR_SVC_MODE AOR CPSR_CPULOCK)
1033#else /* __TARGET_ARCH_ARM < 6 */
1034#ifndef TOPPERS_SAFEG_SECURE
1035 cpsid i
1036#else /* TOPPERS_SAFEG_SECURE */
1037 cpsid if
1038#endif /* TOPPERS_SAFEG_SECURE */
1039#endif /* __TARGET_ARCH_ARM < 6 */
1040
1041 /*
1042 * 割込みコントローラを操作して,割込み優å…
1043ˆåº¦ãƒžã‚¹ã‚¯ã‚’,CPU例外発
1044 * 生時の値に設定する.
1045 */
1046 bl irc_end_exc
1047
1048 /*
1049 * 例外ネストカウントをデクリメントする.
1050 */
1051 ldr r2, =excpt_nest_count
1052 ldr r3, [r2]
1053 subs r3, r3, #1
1054 str r3, [r2] /* 戻りå…
1055ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãªã‚‰ */
1056 bne exc_handler_3 /* exc_handler_3に分岐 */
1057
1058 /*
1059 * タスク用のスタックに戻す.
1060 */
1061 pop {r0,r3}
1062 mov sp, r3
1063
1064 /*
1065 * ディスパッチが必
1066要か判定する.
1067 */
1068 ldr r0, =p_runtsk /* p_runtsk → r0 */
1069 ldr r0, [r0]
1070 ldr r1, =p_schedtsk /* p_schedtsk → r1 */
1071 ldr r1, [r1]
1072 teq r0, r1 /* p_runtskとp_schedtskが同じなら */
1073 beq exc_handler_4 /* exc_handler_4へ */
1074
1075 /*
1076 * コンテキストを保存する.
1077 */
1078 tst r0, r0 /* p_runtskがNULLならdispatcher_0へ */
1079 beq dispatcher_0
1080 stmfd sp!, {r6-r11} /* 非スクラッチレジスタの保存 */
1081 str sp, [r0,#TCB_sp] /* スタックポインタを保存 */
1082 adr r1, ret_exc_r /* 実行再開番地を保存 */
1083 str r1, [r0,#TCB_pc]
1084 b dispatcher /* r0にはp_runtskが格納されている */
1085
1086ALABEL(ret_exc_r)
1087 /*
1088 * コンテキストを復帰する.
1089 */
1090 ldmfd sp!, {r6-r11} /* 非スクラッチレジスタの復帰 */
1091
1092#ifdef TOPPERS_SUPPORT_OVRHDR
1093 /*
1094 * オーバランタイマを動作開始する.
1095 */
1096 bl ovrtimer_start
1097#endif /* TOPPERS_SUPPORT_OVRHDR */
1098
1099 /*
1100 * CPU例外処理からのリターン
1101 *
1102 * CPU例外処理からのリターンにより,CPUロック解除状æ…
1103‹ã«é·ç§»ã™ã‚‹ã‚ˆ
1104 * うにする必
1105要があるが,ARMはCPSRのビットによってCPUロック状æ…
1106‹ã‚’
1107 * 表しているため,CPSRをå…
1108ƒã«æˆ»ã—てリターンすればよい.
1109 */
1110#ifndef TOPPERS_SUPPORT_OVRHDR
1111ALABEL(exc_handler_4)
1112#endif /* TOPPERS_SUPPORT_OVRHDR */
1113ALABEL(exc_handler_3)
1114 pop {r0,r1} /* スタックポインタの調整 */
1115 add sp, sp, r1
1116 add sp, sp, #8 /* スタック上の情
1117報を捨てる */
1118#if __TARGET_ARCH_ARM < 6
1119 ldmfd sp!, {r0} /* 戻りå…
1120ˆã®cpsrをspsrに設定 */
1121 msr spsr_cxsf, r0
1122 ldmfd sp!, {r0-r5,r12,lr,pc}^ /* コンテキストの復帰 */
1123 /* ^付きなので,spsr → cpsr */
1124#else /* __TARGET_ARCH_ARM < 6 */
1125 ldmfd sp!, {r0-r5,r12,lr}
1126 rfefd sp!
1127#endif /* __TARGET_ARCH_ARM < 6 */
1128
1129#ifdef TOPPERS_SUPPORT_OVRHDR
1130ALABEL(exc_handler_4)
1131 /*
1132 * オーバランタイマを動作開始する.
1133 */
1134 tst r0, r0 /* p_runtskがNULLでない場合 */
1135 blne ovrtimer_start
1136 b exc_handler_3
1137#endif /* TOPPERS_SUPPORT_OVRHDR */
1138
1139/*
1140 * カーネル管理外のCPU例外の出å…
1141¥å£å‡¦ç†
1142 */
1143ALABEL(nk_exc_handler_1)
1144 /*
1145 * 【この時点のレジスタ状æ…
1146‹ã€‘
1147 * r1:CPU例外発生前のCPSRのFビットとIビットの値
1148 * r2:excpt_nest_countの番地
1149 * r3:excpt_nest_countの値
1150 * r4:CPU例外ハンドラ番号
1151 * r5:CPU例外の情
1152報を記憶している領域のå…
1153ˆé ­ç•ªåœ°
1154 */
1155
1156 /*
1157 * 例外ネストカウントをインクリメントする.
1158 */
1159 add r3, r3, #1
1160 str r3, [r2]
1161 teq r3, #1 /* CPU例外発生前が非タスクコンテキスト */
1162 bne nk_exc_handler_2 /* ならnk_exc_handler_2に分岐 */
1163
1164 /*
1165 * 非タスクコンテキスト用のスタックに切り換える.
1166 */
1167 mov r3, sp /* この時点のスタックポインタをr3に */
1168 ldr r2, =istkpt /* 非タスクコンテキスト用のスタックに */
1169 ldr sp, [r2]
1170 push {r0,r3} /* 切換え前のスタックポインタを保存 */
1171 /* r0はスペース確保のため */
1172ALABEL(nk_exc_handler_2)
1173 /*
1174 * システム状æ…
1175‹ï¼ˆã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆã¯é™¤ãï¼‰ã‚’,CPU例外発生時の状æ…
1176‹ã¸
1177 */
1178 orr r1, r1, #CPSR_SVC_MODE
1179 msr cpsr_c, r1
1180
1181 /*
1182 * CPU例外ハンドラの呼出し
1183 */
1184 ldr r2, =exc_table /* CPU例外ハンドラテーブルの読込み */
1185 ldr r3, [r2,r4,lsl #2] /* CPU例外ハンドラの番地 → r3 */
1186 mov r0, r5 /* CPU例外の情
1187報を記憶している領域の */
1188 /* å…
1189ˆé ­ç•ªåœ°ã‚’第1パラメータに渡す */
1190 mov r1, r4 /* CPU例外番号を第2パラメータに渡す */
1191 mov lr, pc /* CPU例外ハンドラの呼出し */
1192 bx r3
1193
1194 /*
1195 * 例外ネストカウントをデクリメントする.
1196 */
1197 ldr r2, =excpt_nest_count
1198 ldr r3, [r2]
1199 subs r3, r3, #1
1200 str r3, [r2] /* 戻りå…
1201ˆãŒéžã‚¿ã‚¹ã‚¯ã‚³ãƒ³ãƒ†ã‚­ã‚¹ãƒˆãªã‚‰ */
1202 bne exc_handler_3 /* exc_handler_3に分岐 */
1203
1204 /*
1205 * タスク用のスタックに戻す.
1206 */
1207 pop {r0,r3}
1208 mov sp, r3
1209 b exc_handler_3
1210
1211/*
1212 * ステータスレジスタの操作関数
1213 *
1214 * Thumbモードではmrs/msr命令が使用できないため,関数として実現して,
1215 * ARMモードに移行して実行する.
1216 */
1217#ifdef __thumb__
1218
1219 ATEXT
1220 AALIGN(2)
1221 AWEAK(current_cpsr)
1222ALABEL(current_cpsr)
1223 mrs r0, cpsr_cxsf
1224 bx lr
1225
1226 AALIGN(2)
1227 AWEAK(set_cpsr)
1228ALABEL(set_cpsr)
1229 msr cpsr_cxsf, r0
1230 bx lr
1231
1232#endif /* __thumb__ */
1233
1234/*
1235 * 微少時間待
1236ち
1237 *
1238 * キャッシュラインのどの場所にあるかのよって実行時間が変わるため,大
1239 * きめの単位でアラインしている.
1240 */
1241 ATEXT
1242 AALIGN(8)
1243 AGLOBAL(sil_dly_nse)
1244ALABEL(sil_dly_nse)
1245 mov r1, #0
1246 mcr p15, 0, r1, c7, c5, 6 /* 分岐予測å…
1247¨ä½“の無効化 */
1248 asm_inst_sync_barrier r3
1249 subs r0, r0, #SIL_DLY_TIM1
1250 bxls lr
1251ALABEL(sil_dly_nse1)
1252 mcr p15, 0, r1, c7, c5, 6 /* 分岐予測å…
1253¨ä½“の無効化 */
1254 asm_inst_sync_barrier r3
1255 subs r0, r0, #SIL_DLY_TIM2
1256 bhi sil_dly_nse1
1257 bx lr
Note: See TracBrowser for help on using the repository browser.