source: azure_iot_hub/trunk/asp3_dcre/arch/rx630_gcc/prc_support.S@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

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