source: rubycfg_asp/trunk/asp_dcre/arch/rx630_gcc/prc_support.S@ 313

Last change on this file since 313 was 313, 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: 29.6 KB
Line 
1;
2; TOPPERS/ASP Kernel
3; Toyohashi Open Platform for Embedded Real-Time Systems/
4; Advanced Standard Profile Kernel
5;
6; Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7; Toyohashi Univ. of Technology, JAPAN
8; Copyright (C) 2007 by Embedded and Real-Time Systems Laboratory
9; Graduate School of Information Science, Nagoya Univ., JAPAN
10; Copyright (C) 2010 by Witz Corporation, JAPAN
11; Copyright (C) 2013 by Mitsuhiro Matsuura
12;
13; 上記著作権者
14は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
15; ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
16; 変・再é…
17å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
18; (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
19; 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
20; スコード中に含まれていること.
21; (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
22; 用できる形で再é…
23å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
24å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
25; 者
26マニュアルなど)に,上記の著作権表示,この利用条件および下記
27; の無保証規定を掲載すること.
28; (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
29; 用できない形で再é…
30å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
31; と.
32; (a) 再é…
33å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
34マニュアルなど)に,上記の著
35; 作権表示,この利用条件および下記の無保証規定を掲載すること.
36; (b) 再é…
37å¸ƒã®å½¢æ…
38‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
39; 報告すること.
40; (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
41; 害からも,上記著作権者
42およびTOPPERSプロジェクトをå…
43è²¬ã™ã‚‹ã“と.
44; また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
45; 由に基づく請求からも,上記著作権者
46およびTOPPERSプロジェクトを
47; å…
48è²¬ã™ã‚‹ã“と.
49;
50; 本ソフトウェアは,無保証で提供されているものである.上記著作権者
51お
52; よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
53; に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
54; アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
55; の責任を負わない.
56;
57; @(#) $Id: prc_support.S 313 2017-07-23 04:50:32Z coas-nagasima $
58;
59
60;
61; プロセッサ依存モジュール アセンブリ言語部(RX630用)
62;
63#define TOPPERS_MACRO_ONLY
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
69;
70; ディスパッチャおよび割込み(CPU例外)出å…
71¥ã‚Šå£ã®ãƒ«ãƒ¼ãƒ«:
72; 動作モードを以下のように定義する.
73; ディスパッチャモード:
74; CPUロック状æ…
75‹, 割込み優å…
76ˆåº¦ãƒžã‚¹ã‚¯å…
77¨è§£é™¤çŠ¶æ…
78‹,
79; タスクコンテキスト(intnest = 0), タスクスタック
80; 割込み(CPU例外)処理モード
81; å…
82¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
83‹(PSWレジスタIビット = 0),
84; 割込み優å…
85ˆåº¦ãƒžã‚¹ã‚¯å…
86¨è§£é™¤ã§ãªã„状æ…
87‹(IPL != 0)
88; 割込みコンテキスト(intnest != 0), 割込みスタック
89;
90; カーネル管理外割込みのサポート有無と, CPUロック状æ…
91‹, 割込み優å…
92ˆåº¦
93; マスクå…
94¨è§£é™¤çŠ¶æ…
95‹ã®é–¢ä¿‚は以下の通りである.
96; カーネル管理外割込み未サポート時:
97; CPUロック状æ…
98‹(PSWレジスタIビット = 0)
99; 割込み優å…
100ˆåº¦ãƒžã‚¹ã‚¯å…
101¨è§£é™¤çŠ¶æ…
102‹(IPL = 0)
103; カーネル管理外割込みサポート時:
104; CPUロック状æ…
105‹
106; (PSWレジスタIビット = 0, IPL = IPL_LOCK, lock_flag = true)
107; 割込み優å…
108ˆåº¦ãƒžã‚¹ã‚¯å…
109¨è§£é™¤çŠ¶æ…
110‹(saved_ipl = 0)
111;
112; 各構造体ポインタを以下のように各レジスタにアサインする.
113; r15 = p_runtsk ただしディスパッチャの各出口では無効
114; r14 = *p_runtsk dispatcher の中では p_runtsk 確定時に再取得する
115; 各å…
116¥ã‚Šå£ã‹ã‚‰æœ€åˆã«å¤‰æ•°ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã¨ãã«ä¸Šè¨˜ãƒ¬ã‚¸ã‚¹ã‚¿ã«ä¿å­˜ã™ã‚‹.
117;
118; 構造体アライメントへの対応
119; 構造体アライメントが4Byte(アンパック)の場合:
120; 一般的なレジスタ相対アドレッシングが可能
121; 例: mov.l #__kernel_p_runtsk, r15
122; mov.l r0, TCB_sp[r15]
123; 構造体アライメントが4Byteではない(パック)の場合:
124; mov.lのようにロングサイズ指定の場合、相対値は4の倍数のみ有効
125; このため, 一度対象アドレスを求めてからアクセスする必
126要がある
127; 例: mov.l #__kernel_p_runtsk, r15
128; add #TCB_sp, r15, r5
129; mov.l r0, [r5]
130; 各オフセット値を判断し, 条件アセンブルによりコードを切り替える
131;
132
133;
134; 構造体アクセスのオフセット定義
135;
136#include "offset.h"
137
138;
139; 各種EQU定義(Hファイルの#define定義)
140;
141#include "target_config.h"
142#include "prc_config.h"
143
144 .global __kernel_istkpt
145
146 .global __kernel_p_runtsk
147 .global __kernel_p_schedtsk
148 .global __kernel_reqflg
149 .global __kernel_dspflg
150
151 .global __kernel_dispatch
152 .global __exit_and_dispatch
153 .global __kernel_start_r
154 .global __kernel_call_texrtn
155 .global _kernel_interrupt
156 .global _kernel_exception
157 .global __kernel_intnest
158 .global __kernel_call_exit_kernel
159 .global __kernel_start_dispatch
160
161 .global _ext_tsk
162 .global __kernel_exit_kernel
163
164#if TIPM_LOCK != -15
165 .global __kernel_lock_flag
166 .global __kernel_saved_ipl
167#endif
168
169 .global __kernel_break_wait
170 .global _sil_dly_nse
171
172#if LOG_INH_ENTER_ENABLE == 1
173 .global _kernel_log_inh_enter
174#endif /* LOG_INH_ENTER_ENABLE == 1 */
175#if LOG_INH_LEAVE_ENABLE == 1
176 .global _kernel_log_inh_leave
177#endif /* LOG_INH_LEAVE_ENABLE == 1 */
178#if LOG_EXC_ENTER_ENABLE == 1
179 .global _kernel_log_exc_enter
180#endif /* LOG_EXC_ENTER_ENABLE == 1 */
181#if LOG_EXC_LEAVE_ENABLE == 1
182 .global _kernel_log_exc_leave
183#endif /* LOG_EXC_LEAVE_ENABLE == 1 */
184#if LOG_DSP_ENTER_ENABLE == 1
185 .global _kernel_log_dsp_enter
186#endif /* LOG_DSP_ENTER_ENABLE == 1 */
187#if LOG_DSP_LEAVE_ENABLE == 1
188 .global _kernel_log_dsp_leave
189#endif /* LOG_DSP_LEAVE_ENABLE == 1 */
190
191;
192; TCB_sp への書込みマクロ
193;
194.macro st_TCB_sp src, tcb, tmp
195#if (TCB_sp % 4) == 0
196 mov.l \src, TCB_sp[\tcb]
197#else
198 add #TCB_sp, \tcb, \tmp
199 mov.l \src, [\tmp]
200#endif
201.endm
202
203;
204; TCB_sp からの読出しマクロ
205;
206.macro ld_TCB_sp dst, tcb, tmp
207#if (TCB_sp % 4) == 0
208 mov.l TCB_sp[\tcb], \dst
209#else
210 add #TCB_sp, \tcb, \tmp
211 mov.l [tmp], \dst
212#endif
213.endm
214
215;
216; TCB_pc への書込みマクロ
217;
218.macro st_TCB_pc src, tcb, tmp
219#if (TCB_pc % 4) == 0
220 mov.l \src, TCB_pc[\tcb]
221#else
222 add #TCB_pc, \tcb, \tmp
223 mov.l \src, [\tmp]
224#endif
225.endm
226
227;
228; TCB_pc からの読出しマクロ
229;
230.macro ld_TCB_pc dst, tcb, tmp
231#if (TCB_pc % 4) == 0
232 mov.l TCB_pc[\tcb], \dst
233#else
234 add #TCB_pc, \tcb, \tmp
235 mov.l [\tmp], \dst
236#endif
237.endm
238
239;
240; TCB_texptn からの読出しマクロ
241;
242.macro ld_TCB_texptn dst, tcb, tmp
243#if (TCB_texptn % 4) == 0
244 mov.l TCB_texptn[\tcb], \dst
245#else
246 add #TCB_texptn, \tcb, \tmp
247 mov.l [\tmp], \dst
248#endif
249.endm
250
251;
252; TCB_p_tinib からの読出しマクロ
253;
254.macro ld_TCB_p_tinib dst, tcb, tmp
255#if (TCB_p_tinib % 4) == 0
256 mov.l TCB_p_tinib[\tcb], \dst
257#else
258 add #TCB_p_tinib, \tcb, \tmp
259 mov.l [\tmp], \dst
260#endif
261.endm
262
263;
264; TINIB_exinf からの読出しマクロ
265;
266.macro ld_TINIB_exinf dst, tinib, tmp
267#if (TINIB_exinf % 4) == 0
268 mov.l TINIB_exinf[\tinib], \dst
269#else
270 add #TINIB_exinf, \tinib, \tmp
271 mov.l [\tmp], \dst
272#endif
273.endm
274
275;
276; TINIB_task からの読出しマクロ
277;
278.macro ld_TINIB_task dst, tinib, tmp
279#if (TINIB_task % 4) == 0
280 mov.l TINIB_task[\tinib], \dst
281#else
282 add #TINIB_task, \tinib, \tmp
283 mov.l [\tmp], \dst
284#endif
285.endm
286
287
288 .section P, CODE
289
290;
291; APIからのタスクディスパッチャå…
292¥å£
293;
294; 呼び出し条件:
295; ・ディスパッチャモード(ファイルヘッダ参ç…
296§)
297;
298; ここでは, コンテキストの退避と, 実行再開番地の設定をする.
299;
300__kernel_dispatch:
301 pushm r6-r13 ; 非スクラッチレジスタ保存
302 mov.l #__kernel_p_runtsk, r15
303 mov.l [r15], r14
304 st_TCB_sp r0, r14, r5 ; スタックポインタをTCBに保存
305 st_TCB_pc #dispatch_r, r14, r5 ; 実行再開番地をTCBに保存
306 bra dispatcher
307
308;
309; APIへのタスクディスパッチャ出口
310;
311; 呼び出し条件:
312; ・ディスパッチャモード(ファイルヘッダ参ç…
313§)
314;
315; ここでは, タスク例外ハンドラ呼出しと, コンテキストの復帰をする.
316;
317dispatch_r:
318 btst #TCB_enatex_bit, TCB_enatex[r14].b ; タスク例外処理許可?
319 bz dispatch_r_rts
320 ld_TCB_texptn r5, r14, r4 ; 保留例外要因があるか?
321 cmp #0, r5
322 bz dispatch_r_rts
323 bsr __kernel_call_texrtn ; タスク例外ハンドラ呼出し処理実行
324dispatch_r_rts:
325 popm r6-r13 ; 非スクラッチレジスタ復帰
326 rts ; dispatch 呼び出しå…
327ƒã¸æˆ»ã‚‹.
328
329;
330; タスク起動処理(タスクå…
331ˆé ­ã¸ã®ã‚¿ã‚¹ã‚¯ãƒ‡ã‚£ã‚¹ãƒ‘ッチャ出口)
332;
333; 呼び出し条件:
334; ・ディスパッチャモード(ファイルヘッダ参ç…
335§)
336;
337; ここでは, CPUロック解除状æ…
338‹ã«ã—, タスクを起動する.
339;
340__kernel_start_r:
341 mov.l #_ext_tsk, r5
342 push.l r5 ; 戻り番地をスタックに積む
343 ld_TCB_p_tinib r5, r14, r4
344 ld_TINIB_exinf r1, r5, r4 ; 拡張情
345報を第一引数に設定
346 ld_TINIB_task r5, r5, r4 ; タスクの起動番地を取得
347.if TIPM_LOCK == -15
348 setpsw i ; 割込み許可(CPUロック解除状æ…
349‹)
350.else
351 mov.l #__kernel_lock_flag, r4 ; CPUロック解除状æ…
352‹ã¸
353 mov.l #0, [r4] ; ここに来るときは必
354ず saved_ipl の
355 mvtc #00010000H, psw ; 値は 0 のため, 直値を設定する.
356 ; å…
357¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ…
358‹( I = 1 )
359 ; 割込み優å…
360ˆåº¦ãƒžã‚¹ã‚¯å…
361¨è§£é™¤çŠ¶æ…
362‹( IPL = 0 )
363.endif
364 jmp r5
365
366;
367; カーネル起動からのタスクディスパッチャå…
368¥å£
369;
370; このルーチンは,カーネル起動時に,すべての割込みを禁止した状æ…
371‹
372; (割込みロック状æ…
373‹ã¨åŒç­‰ï¼‰ã§å‘¼ã³å‡ºã•ã‚Œã‚‹ï¼Žã¾ãŸï¼Œå‰²è¾¼ã¿ãƒ¢ãƒ¼ãƒ‰ï¼ˆéž
374; タスクコンテキストと同等)で呼び出されることを想定している.
375;
376; 呼び出し条件:
377; ・割込み(CPU例外)処理モード(ファイルヘッダ参ç…
378§)
379;
380; ここでは, ディスパッチャモードに変更する.
381;
382__kernel_start_dispatch:
383 mov.l #__kernel_intnest, r5
384 mov.w #0, [r5] ; タスクコンテキストに切換え
385#if TIPM_LOCK != -15
386 mvtc #(IPL_LOCK | 00010000H), psw ; å…
387¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ…
388‹
389 ; 割込み優å…
390ˆåº¦ãƒžã‚¹ã‚¯å…
391¨è§£é™¤ã§ãªã„状æ…
392‹
393#endif
394
395;
396; タスク終了(現在のコンテキストを捨てる)からのタスクディスパッチャå…
397¥å£
398;
399; 呼び出し条件:
400; ・ディスパッチャモード(ファイルヘッダ参ç…
401§)
402;
403; ここでは, 何もすることはない.
404; なお, p_runtsk のアドレス取得だけは行なう.
405;
406__exit_and_dispatch:
407 mov.l #__kernel_p_runtsk, r15
408
409;
410; ディスパッチャ本体
411;
412; 呼び出し条件:
413; ・すべてのタスクのコンテキストは保存されている.
414;
415; dispatcher 呼出時のスタック:
416; ・__kernel_dispatch からきた場合 : タスクスタック
417; ・exit_and_dispatch からきた場合:
418; exit_task からきた場合 : タスクスタック
419; カーネル起動時(__kernel_start_dispatch) : 割込みスタック
420; ・ret_int からきた場合 : タスクスタック
421; ・dispatcher_idle_loop からきた場合 : 割込みスタック
422;
423dispatcher:
424.if LOG_DSP_ENTER == 1
425 push.l r15
426 mov.l r14, r1 ; 引数(ディスパッチå…
427ƒTCB)を設定
428 bsr _kernel_log_dsp_enter
429 pop.l r15
430.endif
431 mov.l #__kernel_p_schedtsk, r5
432 mov.l [r5], [r15] ; p_schedtsk を p_runtsk に
433 mov.l [r15], r14
434 cmp #0, r14
435 bz dispatcher_pre_idle ; schedtsk がなければアイドルループへ
436 ld_TCB_sp r0, r14, r5 ; タスクスタックポインタを復帰
437.if LOG_DSP_LEAVE == 1
438 push.l r14
439 mov.l r14, r1 ; 引数(ディスパッチå…
440ˆTCB)を設定
441 bsr _kernel_log_dsp_leave
442 pop.l r14
443.endif
444 ld_TCB_pc r5, r14, r4
445 jmp r5 ; 実行再開番地へジャンプ
446
447;
448; schdedtskがNULLの場合はアイドルループにå…
449¥ã‚‹
450; アイドルループは割込み処理モードで動作させる
451;
452; ここで割込みモードに切り換えるのは,ここで発生する割込み処理に
453; どのスタックを使うかという問題の解決と,割込みハンドラ内
454でのタ
455; スクディスパッチの防止という2つの意味がある.
456;
457dispatcher_pre_idle:
458 mov.l #__kernel_istkpt,r5
459 mov.l [r5], r0 ; 割込み用のスタックへ切替え
460 mov.l #__kernel_intnest, r5
461 mov.w #1, [r5] ; 非タスクコンテキストに切換え
462#if TIPM_LOCK != -15
463 mov.l #__kernel_lock_flag, r5 ; CPUロック解除状æ…
464‹ã¸
465 mov.l #0, [r5]
466 mvtc #0, psw ; 優å…
467ˆåº¦0の割込み処理中を偽装
468
469#endif
470
471dispatcher_idle_loop:
472 setpsw i ; å…
473¨å‰²è¾¼ã¿è¨±å¯
474 clrpsw i ; å…
475¨å‰²è¾¼ã¿ç¦æ­¢
476
477 mov.l #__kernel_reqflg, r5 ; reqflg が FALSE なら
478 mov.l [r5], r4
479 cmp #0, r4
480 bz dispatcher_idle_loop ; アイドルループを繰り返す
481 mov.l #0, [r5] ; reqflgがtrueならfalseにする
482 mov.l #__kernel_intnest, r5
483 mov.w #0, [r5] ; タスクコンテキストに切換え
484#if TIPM_LOCK != -15
485 mov.l #__kernel_lock_flag, r5 ; CPUロック状æ…
486‹ã¸
487 mov.l #1, [r5]
488 mov.l #__kernel_saved_ipl, r5
489 mov.l #0, [r5]
490 mvtc #(IPL_LOCK | PSW_I_MASK), psw ; å…
491¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ…
492‹
493 ; 割込み優å…
494ˆåº¦ãƒžã‚¹ã‚¯å…
495¨è§£é™¤ã§ãªã„状æ…
496‹
497#endif
498 bra dispatcher ; dispatcher へ戻る
499
500
501;
502; カーネルの終了処理の呼出し
503;
504; モードとスタックを非タスクコンテキスト用に切り替え.
505;
506 .global __kernel_call_exit_kernel
507__kernel_call_exit_kernel:
508#if TIPM_LOCK != -15
509 clrpsw i ; å…
510¨å‰²è¾¼ã¿ç¦æ­¢
511 mov.l #__kernel_lock_flag, r5 ; CPUロック解除状æ…
512‹ã¸
513 mov.l #0, [r5]
514#endif
515 mov.l #__kernel_istkpt, r5
516 mov.l [r5], r0 ; 割込み用のスタックへ切替え
517 mov.l #__kernel_intnest, r5
518 mov.w #1, [r5] ; 非タスクコンテキストに切換え
519 bsr __kernel_exit_kernel
520 bra __kernel_call_exit_kernel
521
522
523;
524; 割込み(CPU例外)からのタスクディスパッチャå…
525¥å£
526;
527; 呼出し条件:
528; ・å…
529¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯çŠ¶æ…
530‹(PSWレジスタIビット = 0)
531; ・割込み優å…
532ˆåº¦ãƒžã‚¹ã‚¯å…
533¨è§£é™¤ã§ãªã„状æ…
534‹(IPL != 0)
535; ・タスクコンテキスト(intnest=0)
536; ・使用スタックはタスクスタック
537; ・reqflg = true
538;
539; ここでは, ディスパッチャモードに変更し, reqflgをOFFにしてから,
540; 遅
541延ディスパッチの有無を判断する.
542;
543
544;
545; ret_intå…
546ˆé ­ã§ã‚¹ã‚¿ãƒƒã‚¯ã«ç©ã¾ã‚Œã¦ã„ã‚‹PSWレジスタへのオフセット
547; ACC + FPSW + R14--R15 + R1--R5 + PC
548;
549 .equ RET_INT_GET_PSW_OFFSET, (8+4+28+4)
550
551ret_int:
552.if TIPM_LOCK == -15
553 mov.l RET_INT_GET_PSW_OFFSET[r0], r5 ; 割込み/CPU例外発生前のIPL値取得
554 and #PSW_IPL_MASK, r5
555 mvtc r5, psw ; å…
556¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯(CPUロック)状æ…
557‹
558 ; 割込み/CPU例外発生前の割込み優å…
559ˆåº¦
560.else
561 mov.l #__kernel_lock_flag, r5 ; CPUロック状æ…
562‹ã¸
563 mov.l #1, [r5]
564 mov.l RET_INT_GET_PSW_OFFSET[r0], r5 ; 割込み/CPU例外発生前のIPL値取得
565 and #PSW_IPL_MASK, r5
566 mov.l #__kernel_saved_ipl, r4
567 mov.l r5, [r4]
568 mvtc #(IPL_LOCK | PSW_I_MASK), psw ; å…
569¨å‰²è¾¼ã¿ãƒ­ãƒƒã‚¯è§£é™¤çŠ¶æ…
570‹
571 ; 割込み優å…
572ˆåº¦ãƒžã‚¹ã‚¯å…
573¨è§£é™¤ã§ãªã„状æ…
574‹
575.endif
576 mov.l #__kernel_reqflg, r5
577 mov.l #0, [r5] ; reqflg <--- FALSE
578 mov.l #__kernel_p_runtsk, r15
579 mov.l [r15], r14
580 mov.l #__kernel_dspflg, r5 ; dspflg が FALSE なら ret_int_r へ
581 mov.l [r5], r5
582 cmp #0, r5
583 bz ret_int_r_call_tex
584 mov.l #__kernel_p_schedtsk, r5
585 mov.l [r5], r5
586 cmp r5, r14 ; p_schedtsk と p_runtsk が同じなら
587 beq ret_int_r_call_tex ; ret_int_r_call_tex へ
588 pushm r6-r13 ; 非スクラッチレジスタ保存
589 st_TCB_sp r0, r14, r5 ; スタックポインタをTCBに保存
590 st_TCB_pc #ret_int_r, r14, r5 ; 実行再開番地をTCBに保存
591 bra dispatcher
592
593;
594; 割込み(CPU例外)へのタスクディスパッチャ出口
595;
596; 呼び出し条件:
597; ・ディスパッチャモード(ファイルヘッダ参ç…
598§)
599;
600; ここでは, タスク例外ハンドラ呼出しと, 割込み(CPU例外)処理モードへの
601; 変更と, コンテキストの復帰を行い, 割込み(CUP例外)発生å…
602ƒã¸æˆ»ã‚‹.
603;
604__kernel_break_wait: ;タスクモニタ用ラベル
605ret_int_r:
606 popm r6-r13 ; 非スクラッチレジスタ復帰
607ret_int_r_call_tex:
608 btst #TCB_enatex_bit, TCB_enatex[r14].b ; タスク例外処理許可?
609 bz ret_int_r_rte
610 ld_TCB_texptn r5, r14, r4 ; 保留例外要因があるか?
611 cmp #0, r5
612 bz ret_int_r_rte
613 bsr __kernel_call_texrtn ; タスク例外ハンドラ呼出し処理実行
614ret_int_r_rte:
615#if TIPM_LOCK != -15
616 clrpsw i ; å…
617¨å‰²è¾¼ã¿ç¦æ­¢
618 mov.l #__kernel_lock_flag, r5 ; CPUロック解除状æ…
619‹ã¸
620 mov.l #0, [r5]
621#endif
622 popm r4-r5 ; アキュムレータ復帰
623 mvtaclo r5 ; ACC最下位16bitは0で復帰
624 mvtachi r4
625 popc fpsw ; FPUステータスレジスタ復帰
626 popm r14-r15 ; レジスタ復帰
627 popm r1-r5
628 rte ; 割込み前の処理に戻る
629
630
631;
632; 割込みの出å…
633¥å£å‡¦ç†(アセンブリ言語記述部分)
634;
635; 呼出し条件:
636; ・割込み発生時のH/W処理により, PSWレジスタのIビット=0, IPLは受付け
637; た割込みのIPL.
638; ・スタックは多重割り込みなら割込みスタック, そうでなければ
639; タスクスタック
640; ・割込み発生時のH/W処理により,スタックに割込みからの復帰PCとPSWが
641; 保存されている.
642; ・ベクタテーブルに登録された個別のå…
643¥ã‚Šå£å‡¦ç†ã«ã‚ˆã‚Š, スタックに
644; スクラッチレジスタ(R1-R5)が保存されている.
645;
646; 引数:
647; ・r1:割込み要因番号
648; ・r2:割込みハンドラのアドレス
649;
650; レジスタがスタック上にどのように保存されているかを以下に示す.
651; この図では上が低位, 下が高位のアドレスで, スタックは下から
652; 上方向に向かって積み上げられるものとする.
653;
654; -------------------------
655; | ACC-HI(4byte) |
656; -------------------------(SP + 0)
657; | ACC-LO(4byte) |
658; -------------------------(SP + 4)
659; | FPSW(4byte) |
660; -------------------------(SP + 8)
661; | R14(4byte) |
662; -------------------------(SP + 12)
663; | R15(4byte) |
664; -------------------------(SP + 16)
665; | R1(4byte) |
666; -------------------------(SP + 20)
667; | R2(4byte) |
668; -------------------------(SP + 24)
669; | R3(4byte) |
670; -------------------------(SP + 28)
671; | R4(4byte) |
672; -------------------------(SP + 32)
673; | R5(4byte) |
674; -------------------------(SP + 36)
675; | PC(4byte) |
676; -------------------------(SP + 40)
677; | PSW(4byte) |
678; -------------------------(SP + 44)
679;
680; ここでは, 割込み処理モードに変更してハンドラを実行する.
681;
682; ハンドラからリターンした後は, 多重割込みでなく, かつ reqflg が
683; TRUE になった時に,ret_int へ分岐(遅
684延ディスパッチ)する.
685;
686; 多重割込みかどうかは割込みネストカウンタの値で判定する.
687; intnest != 0 ならば多重割込みであると判定する.
688;
689; reqflg はCPUロック状æ…
690‹ã§ãƒã‚§ãƒƒã‚¯ã™ã‚‹. そうでないと,
691; reqflg チェック後に起動された割込みハンドラ内
692で
693; ディスパッチが要求された場合に,ディスパッチされない.
694;
695_kernel_interrupt:
696 pushm r14-r15 ; スクラッチレジスタを退避
697 pushc fpsw ; FPUステータスレジスタ退避
698 mvfacmi r5
699 shll #16, r5 ; ACC最下位16bitは0とする
700 mvfachi r4
701 pushm r4-r5 ; アキュムレータ退避
702 mov.l #__kernel_intnest, r5
703 mov.w [r5], r4
704 add #1, r4 ; ネスト回数をインクリメント
705 mov.w r4, [r5]
706 cmp #1, r4 ; 多重割り込みかどうか
707 bnz interrupt_from_int ; 加算前が0でなければ多重割込み
708 ; 初段の割込み
709 mov.l r0, r3 ; スタックポインタを取り出し
710 mov.l #__kernel_istkpt, r5 ; 割込み用のスタックへ切替える
711 mov.l [r5], r0
712 push.l r3 ; タスクスタックを保持
713interrupt_from_int: ; 多重割込み
714 setpsw i ; 割込み許可(CPUロック解除状æ…
715‹)
716
717.if LOG_INH_LEAVE == 1
718 push.l r1 ; ログトレースの引数を保持
719.endif
720
721.if LOG_INH_ENTER == 1
722 push.l r2
723 bsr _kernel_log_inh_enter ; ログトレース関数の呼出し
724 ; 引数の割込み要因番号は既にr1にå…
725¥ã£ã¦ã„ã‚‹
726 pop r2
727.endif
728
729 jsr r2 ; Cルーチン呼び出し
730
731.if LOG_INH_LEAVE == 1
732 pop r1 ; 引数に割込み要因番号を設定
733 bsr _kernel_log_inh_leave ; ログトレース関数の呼出し
734.endif
735
736 clrpsw i ; 割込み禁止(CPUロック状æ…
737‹)
738 mov.l #__kernel_intnest, r5
739 mov.w [r5], r4
740 sub #1, r4 ; ネスト回数をデクリメント
741 mov.w r4, [r5]
742 cmp #0, r4 ; 多重割り込みかどうか
743 bnz interrupt_return ; 多重割り込みならリターン
744 ; 初段の割込み
745 pop r0 ; タスクのスタックに戻す
746 mov.l #__kernel_reqflg, r5 ; ディスパッチ要求がないか?
747 mov.l [r5], r5
748 cmp #1, r5
749 bz ret_int ; あれば ret_int へジャンプ
750interrupt_return:
751 popm r4-r5 ; アキュムレータ復帰
752 mvtaclo r5 ; ACC最下位16bitは0で復帰
753 mvtachi r4
754 popc fpsw ; FPUステータスレジスタ復帰
755 popm r14-r15 ; レジスタ復帰
756 popm r1-r5
757 rte ; 割込み前の処理に戻る
758
759
760;
761; CPU例外の出å…
762¥å£å‡¦ç†(アセンブリ言語記述部分)
763;
764; 呼出し条件:
765; ・CPU例外発生時のH/W処理により, PSWレジスタのIビット=0, IPL=0.
766; ・スタックは多重割り込みなら割込みスタック, そうでなければ
767; タスクスタック
768; ・CPU例外発生時のH/W処理により,スタックにCPU例外からの復帰PCと
769; PSWが保存されている.
770; ・ベクタテーブルに登録された個別のå…
771¥ã‚Šå£å‡¦ç†ã«ã‚ˆã‚Š, スタックに
772; スクラッチレジスタ(R1-R5)が保存されている.
773;
774; 引数:
775; ・r1:CPU例外要因番号
776; ・r2:CPU例外ハンドラのアドレス
777;
778; レジスタがスタック上にどのように保存されているかを以下に示す.
779; この図では上が低位, 下が高位のアドレスで, スタックは下から
780; 上方向に向かって積み上げられるものとする.
781; なお, CPU例外要因番号とR6-R13はCPU例外ハンドラ内
782で情
783報を取得
784; する目的で退避しており, 出口処理では保存内
785容を破棄すればよい.
786;
787; -------------------------
788; | CPU例外要因番号 | <----- p_excinf
789; ------------------------- (intptr_t)(p_excinf + 0)
790; | R6(4byte) |
791; ------------------------- (intptr_t)(p_excinf + 4)
792; | R7(4byte) |
793; ------------------------- (intptr_t)(p_excinf + 8)
794; | R8(4byte) |
795; ------------------------- (intptr_t)(p_excinf + 12)
796; | R9(4byte) |
797; ------------------------- (intptr_t)(p_excinf + 16)
798; | R10(4byte) |
799; ------------------------- (intptr_t)(p_excinf + 20)
800; | R11(4byte) |
801; ------------------------- (intptr_t)(p_excinf + 24)
802; | R12(4byte) |
803; ------------------------- (intptr_t)(p_excinf + 28)
804; | R13(4byte) |
805; ------------------------- (intptr_t)(p_excinf + 32)
806; | ACC-HI(4byte) |
807; ------------------------- (intptr_t)(p_excinf + 36)
808; | ACC-LO(4byte) |
809; ------------------------- (intptr_t)(p_excinf + 40)
810; | FPSW(4byte) |
811; ------------------------- (intptr_t)(p_excinf + 44)
812; | R14(4byte) |
813; ------------------------- (intptr_t)(p_excinf + 48)
814; | R15(4byte) |
815; ------------------------- (intptr_t)(p_excinf + 52)
816; | R1(4byte) |
817; ------------------------- (intptr_t)(p_excinf + 56)
818; | R2(4byte) |
819; ------------------------- (intptr_t)(p_excinf + 60)
820; | R3(4byte) |
821; ------------------------- (intptr_t)(p_excinf + 64)
822; | R4(4byte) |
823; ------------------------- (intptr_t)(p_excinf + 68)
824; | R5(4byte) |
825; ------------------------- (intptr_t)(p_excinf + 72)
826; | PC(4byte) |
827; ------------------------- (intptr_t)(p_excinf + 76)
828; | PSW(4byte) |
829; ------------------------- (intptr_t)(p_excinf + 80)
830;
831; ここでは, 割込み処理モードに変更してハンドラを実行する.
832; CPU例外ハンドラに渡すVP型の変数 p_excinf としてISPの値渡す.
833;
834; ハンドラからリターンした後は, 多重割込みでなく, かつ reqflg が
835; TRUE になった時に,ret_int へ分岐(遅
836延ディスパッチ)する.
837;
838; 多重割込みかどうかは割込みネストカウンタの値で判定する.
839; intnest != 0 ならば多重割込みであると判定する.
840;
841; reqflg はCPUロック状æ…
842‹ã§ãƒã‚§ãƒƒã‚¯ã™ã‚‹. そうでないと,
843; reqflg チェック後に起動された割込みハンドラ内
844で
845; ディスパッチが要求された場合に,ディスパッチされない.
846;
847;
848; CPU例外å…
849¥å£å‡¦ç†
850;
851; ここでは, 割込み処理モードに変更してハンドラを実行する.
852;
853
854;
855; CPU例外ハンドラ呼出し後に不要となるスタック情
856報のサイズ
857; EXCNO + R6--R13
858;
859 .equ EXCINF_REG_SIZE, (4+32)
860
861_kernel_exception:
862 pushm r14-r15 ; スクラッチレジスタを退避
863 pushc fpsw
864 mvfacmi r5
865 shll #16, r5 ; ACC最下位16bitは0とする
866 mvfachi r4
867 pushm r4-r5 ; アキュムレータ退避
868 pushm r6-r13 ; 非スクラッチレジスタ保存
869 push.l r1 ; CPU例外要因番号を保持
870 mov.l r0, r3 ; スタックポインタを取り出し
871 mov.l EXC_GET_PSW_OFFSET[r3], r5
872 and #PSW_I_MASK, r5
873 bz exception_nonkernel ; å…
874¨å‰²è¾¼ã¿ç¦æ­¢(CPUロック)状æ…
875‹ãªã‚‰ç®¡ç†å¤–
876#if TIPM_LOCK != -15
877 mov.l EXC_GET_PSW_OFFSET[r3], r5
878 and #PSW_IPL_MASK, r5
879 cmp #IPL_LOCK, r5
880 bgt exception_nonkernel ; IPLがCPUロックレベル以上なら管理外
881#endif
882 mov.l #__kernel_intnest, r5
883 mov.w [r5], r4
884 add #1, r4 ; ネスト回数をインクリメント
885 mov.w r4, [r5]
886 cmp #1, r4 ; 多重割り込みかどうか
887 bnz exception_from_int ; 加算前が0でなければ多重割込み
888 ; 初段の割込み
889 mov.l #__kernel_istkpt, r5 ; 割込み用のスタックへ切替える
890 mov.l [r5], r0
891 push.l r3 ; タスクスタックを保持
892exception_from_int: ; 多重割込み
893 mov.l EXC_GET_PSW_OFFSET[r3], r5
894 mvtc r5, psw ; CPU例外発生前の状æ…
895‹ã«æˆ»ã™
896#if LOG_EXC_LEAVE == 1
897 push.l r1 ; ログトレースの引数を保持
898#endif
899
900#if LOG_EXC_ENTER == 1
901 pushm r2-r3
902 bsr _kernel_log_exc_enter ; ログトレース関数の呼出し
903 ; 引数の割込み要因番号は既にr1にå…
904¥ã£ã¦ã„ã‚‹
905 popm r2-r3
906#endif
907
908 mov.l r3, r1 ; 引数のp_excinfを設定
909 jsr r2 ; Cルーチン呼び出し
910
911.if LOG_EXC_LEAVE == 1
912 pop r1 ; 引数に割込み要因番号を設定
913 bsr _kernel_log_exc_leave ; ログトレース関数の呼出し
914.endif
915
916 clrpsw i ; ここからは必
917ず割込み禁止
918 mov.l #__kernel_intnest, r5
919 mov.w [r5], r4
920 sub #1, r4 ; ネスト回数をデクリメント
921 mov.w r4, [r5]
922 cmp #0, r4 ; 多重割り込みかどうか
923 bnz exception_return ; 多重割り込みならリターン
924 ; 初段の割込み
925 pop r0 ; タスクのスタックに戻す
926 mov.l #__kernel_reqflg, r5 ; ディスパッチ要求がないか?
927 mov.l [r5], r5
928 cmp #1, r5
929 bnz exception_return ; なければリターン
930 add #EXCINF_REG_SIZE, r0 ; CPU例外情
931報の破棄
932 bra ret_int ; あれば ret_int へジャンプ
933
934exception_nonkernel:
935 mov.l #__kernel_intnest, r5
936 mov.w [r5], r4
937 add #1, r4 ; ネスト回数をインクリメント
938 mov.w r4, [r5]
939 cmp #1, r4 ; 多重割り込みかどうか
940 bnz exception_from_nonkernelint ; 加算前が0でなければ多重割込み
941 ; 初段の割込み
942 mov.l #__kernel_istkpt, r5 ; 割込み用のスタックへ切替える
943 mov.l [r5], r0
944 push.l r3 ; タスクスタックを保持
945exception_from_nonkernelint: ; 多重割込み
946 mov.l EXC_GET_PSW_OFFSET[r3], r5
947 mvtc r5, psw ; CPU例外発生前の状æ…
948‹ã«æˆ»ã™
949
950 mov.l r3, r1 ; 引数のp_excinfを設定
951 jsr r2 ; Cルーチン呼び出し
952
953 clrpsw i ; ここからは必
954ず割込み禁止
955 mov.l #__kernel_intnest, r5
956 mov.w [r5], r4
957 sub #1, r4 ; ネスト回数をデクリメント
958 mov.w r4, [r5]
959 cmp #0, r4 ; 多重割り込みかどうか
960 bnz exception_return ; 多重割り込みならリターン
961 ; 初段の割込み
962 pop r0 ; タスクのスタックに戻す
963
964exception_return:
965 add #EXCINF_REG_SIZE, r0 ; CPU例外情
966報の破棄
967 popm r4-r5 ; アキュムレータ復帰
968 mvtaclo r5 ; ACC最下位16bitは0で復帰
969 mvtachi r4
970 popc fpsw ; FPUステータスレジスタ復帰
971 popm r14-r15 ; レジスタ復帰
972 popm r1-r5
973 rte ; 割込み前の処理に戻る
974
975
976;
977; 微少時間待
978ち
979;
980_sil_dly_nse:
981 mov.l #SIL_DLY_TIM1, r5
982 sub r5, r1
983 ble sil_dly_nse_ret
984sil_dly_nse_loop:
985 mov.l #SIL_DLY_TIM2, r5
986 sub r5, r1
987 bgt sil_dly_nse_loop
988sil_dly_nse_ret:
989 rts
990
991 .end
992
Note: See TracBrowser for help on using the repository browser.