|
|
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 によって生成されました。 |