source: EcnlProtoTool/trunk/asp3_dcre/arch/arm_gcc/common/core_support.S@ 279

Last change on this file since 279 was 279, checked in by coas-nagasima, 7 years ago

ファイルを追加、更新。

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