cpu_support.S

説明を見る。
00001 /* 
00002  *
00003  *  TOPPERS/FDMP Kernel
00004  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00005  *      Function Distributed Multiprocessor Kernel
00006  *
00007  *  Copyright (C) 2005 by Embedded and Real-Time Systems Laboratory
00008  *              Graduate School of Information Science, Nagoya Univ., JAPAN  
00009  * 
00010  * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
00011  * によって公表されている GNU General Public License の Version 2 に記
00012  * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
00013  * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
00014  * 利用と呼ぶ)することを無償で許諾する.
00015  * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00016  *     権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00017  *     スコード中に含まれていること.
00018  * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00019  *     用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00020  *     者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00021  *     の無保証規定を掲載すること.
00022  * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00023  *     用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00024  *     と.
00025  *   (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00026  *       作権表示,この利用条件および下記の無保証規定を掲載すること.
00027  *   (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00028  *       報告すること.
00029  * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00030  *     害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00031  *
00032  * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00033  * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00034  * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00035  * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00036  *
00037  *  @(#) $Id: cpu_support.S,v 1.2 2006/03/13 07:34:04 honda Exp $
00038  */
00039 
00040 #define _MACRO_ONLY
00041 
00042 /*
00043  *  アプリケーションと共通のインクルードファイル
00044  */
00045 #include <kernel.h>
00046 
00047 /*
00048  *  ターゲット依存情報の定義
00049  */
00050 #include <t_config.h>
00051 
00052 #include "fdmp_kernel.h"
00053 #include "offset.h"
00054 #include <nios2.h>
00055 
00056     .set noat
00057     .section .exceptions, "xa"
00058     .align 2
00059     .global _irq_entry
00060     .type   _irq_entry, @function
00061 _irq_entry:
00062     /*
00063      *  例外要因の判定
00064      */
00065     rdctl   et, estatus
00066     andi    et, et, 1
00067     beq     et, zero, _check_trap
00068     rdctl   et, ipending
00069     beq     et, zero, _check_trap
00070 
00071     
00072    /*
00073     * 例外要因は割込み
00074     */
00075     addi ea, ea, -4      /* 戻り番地をデクリメント */
00076 
00077     addi  sp, sp, -76    /* レジスタの保存 */
00078     rdctl et, estatus
00079     stw   et,   0(sp)
00080     stw   at,   4(sp)
00081     stw   r2,   8(sp)
00082     stw   r3,  12(sp)
00083     stw   r4,  16(sp)
00084     stw   r5,  20(sp)
00085     stw   r6,  24(sp)
00086     stw   r7,  28(sp)
00087     stw   r8,  32(sp)
00088     stw   r9,  36(sp)
00089     stw   r10, 40(sp)
00090     stw   r11, 44(sp)
00091     stw   r12, 48(sp)
00092     stw   r13, 52(sp)
00093     stw   r14, 56(sp)
00094     stw   r15, 60(sp)
00095     stw   fp,  64(sp)
00096     stw   ra,  68(sp)
00097     stw   ea,  72(sp)
00098 
00099     /*
00100      * 多重割込みか判定
00101      */
00102     ldw   r3, %gprel(interrupt_count)(gp)  /* ネスト回数のチェック */
00103     bltu  zero, r3,  nest_int
00104 
00105     movhi r2, %hiadj(STACKTOP-4)
00106     addi  r2, r2, %lo(STACKTOP-4)
00107     stw   sp, 0(r2)     /* スタックポインタの保存 */        
00108     mov   sp, r2        /* スタックポインタの入れ替え */
00109 nest_int:
00110     /*
00111      *  割込み要因の判定と呼び出し
00112      */
00113     call int_handler_call
00114 
00115 ret_from_int:
00116     ldw   r3, %gprel(interrupt_count)(gp)   
00117     bltu  zero, r3, res_reg_and_ret /* ネスト回数が1以上なら戻る */
00118 
00119     ldw   r2, 0(sp)                 /* スタックポインタを戻す */
00120     mov   sp, r2                    /* スタックポインタを戻す */
00121 
00122     ldw   r3, %gprel(reqflg)(gp)    /* reqflgのチェック */
00123     beq   r3, zero, res_reg_and_ret
00124     br    ret_int
00125 
00126 res_reg_and_ret:
00127     ldw   et,   0(sp)  /* レジスタの復帰 */
00128     wrctl estatus, et
00129     ldw   at,   4(sp)
00130     ldw   r2,   8(sp)
00131     ldw   r3,  12(sp)
00132     ldw   r4,  16(sp)
00133     ldw   r5,  20(sp)
00134     ldw   r6,  24(sp)
00135     ldw   r7,  28(sp)
00136     ldw   r8,  32(sp)
00137     ldw   r9,  36(sp)
00138     ldw   r10, 40(sp)
00139     ldw   r11, 44(sp)
00140     ldw   r12, 48(sp)
00141     ldw   r13, 52(sp)
00142     ldw   r14, 56(sp)
00143     ldw   r15, 60(sp)
00144     ldw   fp,  64(sp)
00145     ldw   ra,  68(sp)
00146     ldw   ea,  72(sp)
00147     addi  sp, sp, 76        
00148     eret      
00149 
00150 
00151 _check_trap:        
00152     /*
00153      *  Trapか判定
00154      */
00155     ldw   et, -4(ea)               /* 例外を出した命令を取得 */
00156     xorhi et, et, 0x003b           /*  上位16bit             */
00157     xori  et, et, 0x683a           /*  下位16bit             */
00158     beq   et, zero, trap_handler
00159 
00160 _check_exc:
00161     addi  sp, sp, -76
00162     rdctl et,   estatus
00163     stw   et,    0(sp)
00164     stw   at,    4(sp)
00165     stw   r2,    8(sp)
00166     stw   r3,   12(sp)
00167     stw   r4,   16(sp)
00168     stw   r5,   20(sp)
00169     stw   r6,   24(sp)
00170     stw   r7,   28(sp)
00171     stw   r8,   32(sp)
00172     stw   r9,   36(sp)
00173     stw   r10,  40(sp)
00174     stw   r11,  44(sp)
00175     stw   r12,  48(sp)
00176     stw   r13,  52(sp)
00177     stw   r14,  56(sp)
00178     stw   r15,  60(sp)
00179     stw   fp,   64(sp)
00180     stw   ra,   68(sp)
00181     stw   ea,   72(sp)
00182     mov   r4,   sp     /* ハンドラの引数 */
00183 
00184     /*
00185      * 多重割込みか判定
00186      */
00187     ldw   r3, %gprel(interrupt_count)(gp)  /* ネスト回数のチェック */
00188     bltu  zero, r3,  nest_int_exc
00189     
00190     movhi r2, %hiadj(STACKTOP-4)
00191     addi  r2, r2, %lo(STACKTOP-4)
00192     stw   sp, 0(r2)     /* スタックポインタの保存 */        
00193     mov   sp, r2        /* スタックポインタの入れ替え */
00194 nest_int_exc:
00195     
00196     call exc_handler_call  /* CPU例外ハンドラ呼び出しルーチンの実行 */
00197 
00198     br ret_from_int        /* リターン処理 */
00199 
00200 
00201 trap_handler:
00202    /*
00203     *  Trapハンドラー
00204     */
00205     eret  
00206 
00207 
00208 
00209     .set noat
00210     .align  2
00211     .global ret_int
00212     .global ret_exc
00213 ret_int:
00214 ret_exc:
00215     stw   zero, %gprel(reqflg)(gp)   /* reqflg を FALSEに */
00216     ldw   r5,   %gprel(runtsk)(gp)   /* r5 <- runtsk      */
00217     ldw   r6,   %gprel(enadsp)(gp)   /* r6 <- enadsp      */
00218     beq   r6,   zero, ret_int_1      /* enadsp が FALSE なら ret_int_1 へ */
00219     /*
00220      * terflgのチェック
00221      * TRUEならdispatcherに飛ぶ
00222      */
00223     ldw   r6,   TCB_terflg(r5)
00224     bne   r6,   zero, dispatcher
00225     ldw   r4,   %gprel(schedtsk)(gp) /* r4 <- schedtsk    */
00226     beq   r4,   r5, ret_int_1        /* runtsk と schedtskが同じならret_int_1へ */
00227     addi  sp,   sp, -32              /* 残りのレジスタを保存 */
00228     stw   r16,  0(sp)
00229     stw   r17,  4(sp)
00230     stw   r18,  8(sp)
00231     stw   r19, 12(sp)
00232     stw   r20, 16(sp)
00233     stw   r21, 20(sp)
00234     stw   r22, 24(sp)
00235     stw   r23, 28(sp)
00236     stw   sp,  TCB_sp(r5)         /* タスクスタックをTCBに保存 */
00237     movhi r2,  %hiadj(ret_int_r)  /* 実行開始番地を保存        */
00238     addi  r2,  r2, %lo(ret_int_r)
00239     stw   r2,  TCB_pc(r5)         /* 実行再開番地をTCBに保存   */
00240     br    dispatcher
00241 
00242     .global ret_int_r
00243 ret_int_r:
00244     ldw   r16,  0(sp)       /* レジスタを復帰 */
00245     ldw   r17,  4(sp)
00246     ldw   r18,  8(sp)
00247     ldw   r19, 12(sp)
00248     ldw   r20, 16(sp)
00249     ldw   r21, 20(sp)
00250     ldw   r22, 24(sp)
00251     ldw   r23, 28(sp)
00252     addi  sp, sp, 32    
00253 ret_int_1:
00254     /*
00255      *  タスク例外ルーチンの起動    
00256      *  ret_int_r は dispatcher から呼び出されるため,
00257      *  tcbのアドレスは r4 に入っている
00258      */
00259     ldw  r5, TCB_enatex(r4)       /* r5 <- enatex */
00260 #if TCB_enatex_mask > 0xffff
00261     andhi r6, r5, %hi(TCB_enatex_mask)
00262 #else
00263     andi r6, r5, %lo(TCB_enatex_mask)
00264 #endif /* TCB_enatex_mask > 0xffff */
00265     andhi r6, r5, 4
00266     beq  r6, zero, ret_int_2      /* enatex が FALSE ならリターン */
00267     ldw  r7, TCB_texptn(r4)       /* r7 <- texptn, texptnが0でなければ */
00268     beq  zero, r7, ret_int_2      
00269     call dispatch_call_texrtn     /* タスク例外ルーチンの呼び出し */
00270 
00271 ret_int_2:
00272     ldw   et,   0(sp)    /* レジスタを復帰 */
00273     wrctl estatus, et
00274     ldw   at,   4(sp)
00275     ldw   r2,   8(sp)
00276     ldw   r3,  12(sp)
00277     ldw   r4,  16(sp)
00278     ldw   r5,  20(sp)
00279     ldw   r6,  24(sp)
00280     ldw   r7,  28(sp)
00281     ldw   r8,  32(sp)
00282     ldw   r9,  36(sp)
00283     ldw   r10, 40(sp)
00284     ldw   r11, 44(sp)
00285     ldw   r12, 48(sp)
00286     ldw   r13, 52(sp)
00287     ldw   r14, 56(sp)
00288     ldw   r15, 60(sp)
00289     ldw   fp,  64(sp)
00290     ldw   ra,  68(sp)
00291     ldw   ea,  72(sp)
00292     addi  sp, sp, 76        
00293     eret      
00294 
00295 
00296     
00297 
00298     .global dispatch
00299     .align  2
00300 dispatch:
00301     addi  sp, sp, -40                /* レジスタを保存 */    
00302     stw   r16,  0(sp)
00303     stw   r17,  4(sp)
00304     stw   r18,  8(sp)
00305     stw   r19, 12(sp)
00306     stw   r20, 16(sp)
00307     stw   r21, 20(sp)
00308     stw   r22, 24(sp)
00309     stw   r23, 28(sp)
00310     stw   fp,  32(sp)
00311     stw   ra,  36(sp)
00312     ldw   r4,  %gprel(runtsk)(gp)  /* r4 <- runtsk              */
00313     stw   sp,  TCB_sp(r4)          /* タスクスタックをTCBに保存 */
00314     movhi r5,  %hiadj(dispatch_r)  /* 実行開始番地を保存        */
00315     addi  r5,  r5, %lo(dispatch_r)
00316     stw   r5,  TCB_pc(r4)          /* 実行再開番地をTCBに保存   */
00317     br    dispatcher
00318 
00319 dispatch_r:
00320     ldw   r16,  0(sp)              /* レジスタを復帰 */
00321     ldw   r17,  4(sp)
00322     ldw   r18,  8(sp)
00323     ldw   r19, 12(sp)
00324     ldw   r20, 16(sp)
00325     ldw   r21, 20(sp)
00326     ldw   r22, 24(sp)
00327     ldw   r23, 28(sp)
00328     ldw   fp,  32(sp)     
00329     /*
00330      * タスク例外ルーチンの起動
00331      *  dispatch_r は dispatcher から呼び出されるため,
00332      *  tcb のアドレスは r4 に入っている
00333      */    
00334     ldw  r5, TCB_enatex(r4)       /* r5 <- enatex */
00335 #if TCB_enatex_mask > 0xffff
00336     andhi r6, r5, %hi(TCB_enatex_mask)
00337 #else
00338     andi r6, r5, %lo(TCB_enatex_mask)
00339 #endif /* TCB_enatex_mask > 0xffff */
00340     beq  r6, zero, dispatch_r_1   /* enatex が FALSE ならリターン */
00341     ldw  r7, TCB_texptn(r4)       /* r7 <- texptn, texptnが0でなければ */
00342     beq  r7, zero, dispatch_r_1    
00343     call dispatch_call_texrtn     /* タスク例外ルーチンの呼び出し */
00344 
00345 dispatch_r_1:
00346     ldw   ra, 36(sp)              /* 残りのレジスタを復帰 */    
00347     addi  sp, sp, 40                
00348     ret
00349 
00350 
00351 
00352     .global exit_and_dispatch
00353 exit_and_dispatch:
00354     stw      zero, %gprel(interrupt_count)(gp)  /* interrupt_count をクリア */
00355 dispatcher:
00356     /*
00357      * ここは割込み禁止で来ること
00358      */    
00359     ldw   r4,   %gprel(schedtsk)(gp) /* r4 <- schedtsk              */
00360     stw   r4,   %gprel(runtsk)(gp)   /* schedtsk を runtskに        */
00361     beq   r4,   zero, dispatcher_1   /* schedtskがあるか            */
00362     ldw   sp,   TCB_sp(r4)           /* TCBからタスクスタックを復帰 */
00363     ldw   r5,   TCB_pc(r4)           /* TCBから実行再開番地を復帰   */
00364     jmp   r5
00365 dispatcher_1:
00366     /*
00367      * ここで割込みモードに切り替えるのは,ここで発生する割込み処理
00368      * にどのスタックを使うかという問題の解決と,割込みハンドラ内で
00369      * のタスクディスパッチの防止という2つの意味がある.
00370      */
00371     movhi sp, %hiadj(STACKTOP)            /* 割込みスタックに変更  */
00372     addi  sp, sp, %lo(STACKTOP)              
00373     movi  r5, 1                           /* interrupt_count を1に */
00374     stw   r5, %gprel(interrupt_count)(gp)  
00375 dispatcher_2:
00376     wrctl status, r5      /* 割込みの許可 */
00377     nop
00378     nop
00379     nop
00380     nop
00381     wrctl status, zero                      /* 割込みの禁止             */
00382     ldw   r6, %gprel(reqflg)(gp)            /* r6 <- reqflg             */
00383     beq   r6, zero, dispatcher_2            /* reqflg が FALSE なら     */
00384     stw   zero, %gprel(interrupt_count)(gp) /* interrupt_count をクリア */ 
00385     stw   zero, %gprel(reqflg)(gp)          /* reqflg を FALSE に       */ 
00386     br    dispatcher
00387 
00388 
00389     .text
00390     .global activate_r
00391     .align 2
00392 activate_r:
00393 
00394 
00395     ldw   r5,   %gprel(runtsk)(gp) /* r5 <- runtsk        */
00396     ldw   r3,   TCB_tinib(r5)      /* r3 <- tinib         */
00397     stw   zero, TCB_terflg(r5)     /* TCBのterflgのクリア */
00398     movi  r2, 1
00399     wrctl status, r2               /* 割込み許可       */
00400     ldw   r2,   TINIB_task(r3)     /* タスクの実行番地 */
00401     ldw   r4,   TINIB_exinf(r3)    /* 引数(exinf)      */
00402     movhi ra, %hiadj(ext_tsk)
00403     addi  ra, ra, %lo(ext_tsk)
00404     jmp   r2                       /* タスクの実行開始 */
00405 
00406 

Copyright © 2006 by TAKAGI Nobuhisa.
このページは Mon Apr 3 23:49:12 2006 に Doxygen によって生成されました。