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

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

mruby版ECNLプロトタイピング・ツールを追加

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