cpu_support.S

説明を見る。
00001 /*
00002  *  TOPPERS/JSP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Just Standard Profile Kernel
00005  * 
00006  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  * 
00009  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
00010  *  によって公表されている GNU General Public License の Version 2 に記
00011  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
00012  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
00013  *  利用と呼ぶ)することを無償で許諾する.
00014  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00015  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00016  *      スコード中に含まれていること.
00017  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00018  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00019  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00020  *      の無保証規定を掲載すること.
00021  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00022  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00023  *      と.
00024  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00025  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00026  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00027  *        報告すること.
00028  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00029  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00030  * 
00031  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00032  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00033  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00034  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00035  * 
00036  *  @(#) $Id: cpu_support.S,v 1.16 2005/11/12 14:58:46 hiro Exp $
00037  */
00038 
00039 /*
00040  *      プロセッサ依存モジュール アセンブリ言語部(M68040用)
00041  */
00042 
00043 #define _MACRO_ONLY
00044 #include "jsp_kernel.h"
00045 #include "offset.h"
00046 
00047 /*
00048  *  タスクディスパッチャ
00049  *
00050  *  dispatch は,マスタモード・割込み禁止状態で呼び出さなければならな
00051  *  い.exit_and_dispatch も,マスタモード・割込み禁止状態で呼び出すの
00052  *  が原則であるが,カーネル起動時に対応するため,割込みモードで呼び出
00053  *  した場合にも対応している.
00054  */
00055         .text
00056         .globl dispatch
00057         .globl exit_and_dispatch
00058 dispatch:
00059         movem.l %d2-%d7/%a2-%a6, -(%sp) /* レジスタを保存 */
00060         move.l runtsk, %a0              /* A0 を runtsk に */
00061         move.l %sp, TCB_msp(%a0)        /* タスクスタックを保存 */
00062         move.l #dispatch_r, TCB_pc(%a0) /* 実行再開番地を保存 */
00063         jbra dispatcher
00064 
00065 dispatch_r:
00066         movem.l (%sp)+, %d2-%d7/%a2-%a6 /* レジスタを復帰 */
00067         btst.b #TCB_enatex_bit, TCB_enatex(%a0)
00068         jbeq dispatch_r_1               /* enatex が FALSE ならリターン */
00069         tst.l TCB_texptn(%a0)           /* texptn が 0 でなければ           */
00070         jbne call_texrtn                /*   タスク例外処理ルーチンの呼出し */
00071 dispatch_r_1:
00072         rts
00073 
00074 exit_and_dispatch:
00075         or.w #0x1000, %sr               /* マスタモード */
00076 dispatcher:
00077         /*
00078          *  ここではマスタモード・割込み禁止状態でなければならない.
00079          */
00080         move.l schedtsk, %a0
00081         move.l %a0, runtsk              /* schedtsk を runtsk に */
00082         jbeq dispatcher_1               /* runtsk があるか? */
00083         move.l TCB_msp(%a0), %sp        /* タスクスタックを復帰 */
00084         move.l TCB_pc(%a0), %a1         /* 実行再開番地を復帰 */
00085         jmp (%a1)
00086 dispatcher_1:
00087         stop #0x2000                    /* 割込み待ち(割込みモード) */
00088         /*
00089          *  ここで割込みモードに切り換えるのは,ここで発生する割込み処理
00090          *  にどのスタックを使うかという問題の解決と,割込みハンドラ内で
00091          *  のタスクディスパッチの防止という2つの意味がある.
00092          *
00093          *  この stop命令は,IPM を 0 にするが,本来は task_intmask に
00094          *  設定すべきである.M68040 では,stop 命令のパラメータに定数
00095          *  しかとれないため,やむをえず 0 にしている(stop 命令を 8つ
00096          *  並べて,task_intmask の値で飛び分ける手はあるが,そこまで
00097          *  やる意義はないと考えた).
00098          *
00099          *  プロセッサを待ちモードに移行させる処理と,割込み許可とは,
00100          *  不可分に行なう必要がある(M68040 では stop命令で両方行なう
00101          *  ので問題ない).これを不可分に行なわない場合,割込みを許可
00102          *  した直後に割込みが入り,その中でタスクが実行可能状態になる
00103          *  と,実行すべきタスクがあるにもかかわらずプロセッサが待ちモー
00104          *  ドになってしまう.
00105          *
00106          *  割込みを待つ間は,runtsk を NULL(=0)に設定しなければなら
00107          *  ない.このように設定しないと,割込みハンドラから iget_tid 
00108          *  を呼び出した際の動作が仕様に合致しなくなる.
00109          */
00110         or.w #0x1700, %sr               /* マスタモード・割込み禁止 */
00111         tst.l reqflg                    /* reqflg が FALSE なら */
00112         jbeq dispatcher_1               /*      dispatcher_1 へ */
00113         clr.l reqflg                    /* reqflg を FALSE に */
00114         jbra dispatcher
00115         
00116 /*
00117  *  タスク起動時処理
00118  */
00119         .text
00120         .globl activate_r
00121 activate_r:
00122         /*
00123          *  タスク起動直後はタスク例外処理が禁止されているため,ここでタ
00124          *  スク例外処理ルーチンを呼び出す条件は成り立たない.
00125          */
00126 #ifdef SUPPORT_CHG_IPM                  /* t_unlock_cpu 相当の処理 */
00127         move.w %sr, %d0                 /* 割込みマスクを task_intmask に */
00128         and.w #~0x0700, %d0
00129         or.w task_intmask, %d0
00130         move.w %d0, %sr
00131 #else /* SUPPORT_CHG_IPM */
00132         and.w #~0x0700, %sr             /* 割込み許可 */
00133 #endif /* SUPPORT_CHG_IPM */
00134         move.l (%sp)+, %a0              /* タスクの起動番地を a0 に */
00135         jmp (%a0)
00136 
00137 /*
00138  *  割込みハンドラ/CPU例外ハンドラ出口処理
00139  *
00140  *  ret_int は割込みモード・割込み禁止状態で,ret_exc はマスタモード・
00141  *  割込み禁止状態で呼び出さなければならない.また ret_exc は,スクラッ
00142  *  チレジスタを保存した状態で呼び出すこと.
00143  */
00144         .text
00145         .globl ret_int
00146         .globl ret_exc
00147 ret_int:
00148         addq.l #8, %sp                  /* スローアウェイフレームを捨てる */
00149         or.w #0x1000, %sr               /* マスタモード */
00150         movem.l %d0-%d1/%a0-%a1, -(%sp) /* スクラッチレジスタを保存 */
00151 ret_exc:
00152         clr.l reqflg                    /* reqflg を FALSE に */
00153         move.l runtsk, %a0              /* A0 ← runtsk */
00154         tst.l enadsp                    /* enadsp が FALSE なら */
00155         jbeq ret_int_1                  /*         ret_int_1 へ */
00156         cmp.l schedtsk, %a0             /* runtsk と schedtsk が同じなら */
00157         jbeq ret_int_1                  /*                  ret_int_1 へ */
00158         movem.l %d2-%d7/%a2-%a6, -(%sp) /* 残りのレジスタを保存 */
00159         move.l %sp, TCB_msp(%a0)        /* タスクスタックを保存 */
00160         move.l #ret_int_r, TCB_pc(%a0)  /* 実行再開番地を保存 */
00161         jbra dispatcher
00162 
00163 ret_int_r:
00164         movem.l (%sp)+, %d2-%d7/%a2-%a6 /* レジスタを復帰 */
00165 ret_int_1:
00166         btst.b #TCB_enatex_bit, TCB_enatex(%a0)
00167         jbeq ret_int_2                  /* enatex が FALSE ならリターン */
00168         tst.l TCB_texptn(%a0)           /* texptn が 0 ならリターン */
00169         jbeq ret_int_2
00170         jsr call_texrtn                 /* タスク例外処理ルーチンの呼出し */
00171 ret_int_2:
00172 #ifdef SUPPORT_CHG_IPM
00173         move.w 16(%sp), %d0             /* 戻り先の割込みマスクを */
00174         and.w #~0x0700, %d0             /*        task_intmask に */
00175         or.w task_intmask, %d0
00176         move.w %d0, 16(%sp)
00177 #endif /* SUPPORT_CHG_IPM */
00178         movem.l (%sp)+, %d0-%d1/%a0-%a1 /* スクラッチレジスタを復帰 */
00179         rte
00180 
00181 /*
00182  *  微少時間待ち
00183  */
00184         .globl _sil_dly_nse
00185 _sil_dly_nse:
00186         subi.l #SIL_DLY_TIM1, %d0       /* D0 から SIL_DLY_TIM1 を引く */
00187         jbhi _sil_dly_nse_1             /* 結果が 0 以下ならリターン */
00188         rts
00189 _sil_dly_nse_1:
00190         subi.l #SIL_DLY_TIM2, %d0       /* D0 から SIL_DLY_TIM2 を引く */
00191         jbhi _sil_dly_nse_1             /* 結果が 0 より大きければループ */
00192         rts
00193 

Copyright © 2006 by TAKAGI Nobuhisa.
Copyright © 2006 by Kijineko Inc..
このページは Mon Dec 18 17:18:38 2006 に Doxygen によって生成されました。
データ入力からプログラム開発まで!様々なスキルを持ったメンバーが登録しています【@SOHO】