3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
9 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
10 * によって公表されている GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 * @(#) $Id: cpu_support.S,v 1.1 2009/01/31 05:27:37 suikan Exp $
40 * プロセッサ依存モジュール アセンブリ言語部(M68040用)
44 #include "jsp_kernel.h"
50 * dispatch は,マスタモード・割込み禁止状態で呼び出さなければならな
51 * い.exit_and_dispatch も,マスタモード・割込み禁止状態で呼び出すの
52 * が原則であるが,カーネル起動時に対応するため,割込みモードで呼び出
57 .globl exit_and_dispatch
59 movem.l %d2-%d7/%a2-%a6, -(%sp) /* レジスタを保存 */
60 move.l runtsk, %a0 /* A0 を runtsk に */
61 move.l %sp, TCB_msp(%a0) /* タスクスタックを保存 */
62 move.l #dispatch_r, TCB_pc(%a0) /* 実行再開番地を保存 */
66 movem.l (%sp)+, %d2-%d7/%a2-%a6 /* レジスタを復帰 */
67 btst.b #TCB_enatex_bit, TCB_enatex(%a0)
68 jbeq dispatch_r_1 /* enatex が FALSE ならリターン */
69 tst.l TCB_texptn(%a0) /* texptn が 0 でなければ */
70 jbne call_texrtn /* タスク例外処理ルーチンの呼出し */
75 or.w #0x1000, %sr /* マスタモード */
78 * ここではマスタモード・割込み禁止状態でなければならない.
81 move.l %a0, runtsk /* schedtsk を runtsk に */
82 jbeq dispatcher_1 /* runtsk があるか? */
83 move.l TCB_msp(%a0), %sp /* タスクスタックを復帰 */
84 move.l TCB_pc(%a0), %a1 /* 実行再開番地を復帰 */
87 stop #0x2000 /* 割込み待ち(割込みモード) */
89 * ここで割込みモードに切り換えるのは,ここで発生する割込み処理
90 * にどのスタックを使うかという問題の解決と,割込みハンドラ内で
91 * のタスクディスパッチの防止という2つの意味がある.
93 * この stop命令は,IPM を 0 にするが,本来は task_intmask に
94 * 設定すべきである.M68040 では,stop 命令のパラメータに定数
95 * しかとれないため,やむをえず 0 にしている(stop 命令を 8つ
96 * 並べて,task_intmask の値で飛び分ける手はあるが,そこまで
99 * プロセッサを待ちモードに移行させる処理と,割込み許可とは,
100 * 不可分に行なう必要がある(M68040 では stop命令で両方行なう
101 * ので問題ない).これを不可分に行なわない場合,割込みを許可
102 * した直後に割込みが入り,その中でタスクが実行可能状態になる
103 * と,実行すべきタスクがあるにもかかわらずプロセッサが待ちモー
106 * 割込みを待つ間は,runtsk を NULL(=0)に設定しなければなら
107 * ない.このように設定しないと,割込みハンドラから iget_tid
108 * を呼び出した際の動作が仕様に合致しなくなる.
110 or.w #0x1700, %sr /* マスタモード・割込み禁止 */
111 tst.l reqflg /* reqflg が FALSE なら */
112 jbeq dispatcher_1 /* dispatcher_1 へ */
113 clr.l reqflg /* reqflg を FALSE に */
123 * タスク起動直後はタスク例外処理が禁止されているため,ここでタ
124 * スク例外処理ルーチンを呼び出す条件は成り立たない.
126 #ifdef SUPPORT_CHG_IPM /* t_unlock_cpu 相当の処理 */
127 move.w %sr, %d0 /* 割込みマスクを task_intmask に */
129 or.w task_intmask, %d0
131 #else /* SUPPORT_CHG_IPM */
132 and.w #~0x0700, %sr /* 割込み許可 */
133 #endif /* SUPPORT_CHG_IPM */
134 move.l (%sp)+, %a0 /* タスクの起動番地を a0 に */
138 * 割込みハンドラ/CPU例外ハンドラ出口処理
140 * ret_int は割込みモード・割込み禁止状態で,ret_exc はマスタモード・
141 * 割込み禁止状態で呼び出さなければならない.また ret_exc は,スクラッ
142 * チレジスタを保存した状態で呼び出すこと.
148 addq.l #8, %sp /* スローアウェイフレームを捨てる */
149 or.w #0x1000, %sr /* マスタモード */
150 movem.l %d0-%d1/%a0-%a1, -(%sp) /* スクラッチレジスタを保存 */
152 clr.l reqflg /* reqflg を FALSE に */
153 move.l runtsk, %a0 /* A0 ← runtsk */
154 tst.l enadsp /* enadsp が FALSE なら */
155 jbeq ret_int_1 /* ret_int_1 へ */
156 cmp.l schedtsk, %a0 /* runtsk と schedtsk が同じなら */
157 jbeq ret_int_1 /* ret_int_1 へ */
158 movem.l %d2-%d7/%a2-%a6, -(%sp) /* 残りのレジスタを保存 */
159 move.l %sp, TCB_msp(%a0) /* タスクスタックを保存 */
160 move.l #ret_int_r, TCB_pc(%a0) /* 実行再開番地を保存 */
164 movem.l (%sp)+, %d2-%d7/%a2-%a6 /* レジスタを復帰 */
166 btst.b #TCB_enatex_bit, TCB_enatex(%a0)
167 jbeq ret_int_2 /* enatex が FALSE ならリターン */
168 tst.l TCB_texptn(%a0) /* texptn が 0 ならリターン */
170 jsr call_texrtn /* タスク例外処理ルーチンの呼出し */
172 #ifdef SUPPORT_CHG_IPM
173 move.w 16(%sp), %d0 /* 戻り先の割込みマスクを */
174 and.w #~0x0700, %d0 /* task_intmask に */
175 or.w task_intmask, %d0
177 #endif /* SUPPORT_CHG_IPM */
178 movem.l (%sp)+, %d0-%d1/%a0-%a1 /* スクラッチレジスタを復帰 */
186 subi.l #SIL_DLY_TIM1, %d0 /* D0 から SIL_DLY_TIM1 を引く */
187 jbhi _sil_dly_nse_1 /* 結果が 0 以下ならリターン */
190 subi.l #SIL_DLY_TIM2, %d0 /* D0 から SIL_DLY_TIM2 を引く */
191 jbhi _sil_dly_nse_1 /* 結果が 0 より大きければループ */