Guest User

Untitled

a guest
Jul 16th, 2018
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.80 KB | None | 0 0
  1. ;*
  2. ;* TOPPERS/JSP Kernel
  3. ;* Toyohashi Open Platform for Embedded Real-Time Systems/
  4. ;* Just 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) 2003-2007 by Naoki Saito
  9. ;* Nagoya Municipal Industrial Research Institute, JAPAN
  10. ;* Copyright (C) 2003-2004 by Ryosuke Takeuchi
  11. ;* Platform Development Center RICOH COMPANY,LTD. JAPAN
  12. ;*
  13. ;* 上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
  14. ;* によって公表されている GNU General Public License の Version 2 に記
  15. ;* 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
  16. ;* を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
  17. ;* 利用と呼ぶ)することを無償で許諾する.
  18. ;* (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
  19. ;* 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
  20. ;* スコード中に含まれていること.
  21. ;* (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
  22. ;* 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
  23. ;* 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
  24. ;* の無保証規定を掲載すること.
  25. ;* (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
  26. ;* 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
  27. ;* と.
  28. ;* (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
  29. ;* 作権表示,この利用条件および下記の無保証規定を掲載すること.
  30. ;* (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
  31. ;* 報告すること.
  32. ;* (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
  33. ;* 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
  34. ;*
  35. ;* 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
  36. ;* よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
  37. ;* 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
  38. ;* 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
  39. ;*
  40. ;* @(#) $Id: cpu_support.a30,v 1.7 2007/03/23 07:06:35 honda Exp $
  41.  
  42.  
  43. ;
  44. ; プロセッサ依存モジュール アセンブリ言語部(M16C用)
  45. ;
  46.  
  47. ;
  48. ; offset.incはmakeoffset.cとm16coffset.exeコマンドにより
  49. ; 自動生成される.
  50. ;
  51. .include offset.inc
  52.  
  53. .glb __kernel_runtsk
  54. .glb __kernel_schedtsk
  55. .glb __kernel_reqflg
  56. .glb __kernel_enadsp
  57.  
  58. .glb __kernel_dispatch
  59. .glb __kernel_exit_and_dispatch
  60. .glb __kernel_activate_r
  61. .glb __kernel_call_texrtn
  62. .glb __kernel_interrupt
  63. .glb __kernel_intnest
  64.  
  65. .glb _iana_tsk
  66. .glb __kernel_break_wait
  67.  
  68. .section program, code, align
  69. ;
  70. ; タスクディスパッチャ
  71. ;
  72. ; dispatch は,タスクコンテキスト状態・割込み禁止状態で呼び出さなけ
  73. ; ればならない.exit_and_dispatch も,タスクコンテキスト状態・割込
  74. ; み禁止状態で呼び出すのが原則であるが,カーネル起動時に対応するため,
  75. ; 割込みモードで呼び出した場合にも対応している.
  76. ; 呼び出し条件: IPL=0, FLGレジスタIビット=0 (CPUロック状態),
  77. ; intnest = 0(タスクコンテキスト), タスクスタック
  78. ;
  79. __kernel_dispatch:
  80. pushm sb, fb ; スタックへレジスタ保存
  81. mov.w __kernel_runtsk, a0
  82. stc isp, TCB_sp[a0] ; スタックポインタをTCBに保存
  83. mov.w #(dispatch_r>>16), TCB_pc+2[a0] ; 実行再開番地をTCBに保存
  84. mov.w #(dispatch_r & 0ffffh), TCB_pc[a0]
  85. jmp.b dispatcher
  86. ;
  87. ; 呼び出し条件: IPL=0, FLGレジスタIビット=0 (CPUロック状態),
  88. ; intnest = 0(タスクコンテキスト), タスクスタック
  89. ;
  90. ; a0 にはruntsk のアドレスが格納されている
  91. ;
  92. dispatch_r:
  93. popm sb,fb ; タスクスタックからレジスタ復帰
  94. mov.w TCB_enatex[a0], r0
  95. btst TCB_enatex_bit, r0 ; タスク例外処理許可?
  96. jz dispatch_r_1 ; 許可でなければ dispatch_r_1 へ
  97. mov.w TCB_texptn[a0], r0 ; 保留例外要因があるか?
  98. jz dispatch_r_1 ; なければ dispatch_r_1 へ
  99. jmp __kernel_call_texrtn ; タスク例外ハンドラへ
  100. dispatch_r_1: ; タスク例外を実行しない場合
  101. rts ; dispatch 呼び出し元へ戻る.
  102.  
  103.  
  104. ;
  105. ; タスク起動時処理
  106. ;
  107. ; ここでは, CPUロック解除状態にし, タスクを起動する.
  108. ;
  109. ; 呼出条件: FLGレジスタIビット=0 (CPUロック状態), タスクスタック
  110. ; IPL=0, タスクコンテキスト(intnest=0)
  111. ;
  112. __kernel_activate_r:
  113. pop.w a0 ; タスクの起動番地をA1A0に設定
  114. pop.w a1
  115. ldc #0040h, flg ; 割込み許可, ISP, IPL=0
  116. jmpi.a a1a0
  117.  
  118. ;
  119. ; dispatch呼び出し条件:
  120. ; ・すべてのタスクのコンテキストは保存されている.
  121. ; ・FLGレジスタIビット=0 (CPUロック状態)
  122. ; ・コンテキストはタスクコンテキスト(intnest=0)
  123. ;  但し、exit_and_dispatchについてはモニター起動等を考慮
  124. ;  した上記以外の呼び出し条件の対応を行う
  125. ; dispatcher 呼出時のスタック:
  126. ; __kernel_dispatch からきた場合: タスクスタック
  127. ; exit_and_dispatch からきた場合:
  128. ; exit_task からきた場合はタスクスタック
  129. ; カーネル起動時は割込みスタック
  130. ; ret_int からきた場合: 割込みスタック
  131. ; dispatcher_2 での割込み待ちからきた場合: 割込みスタック
  132. ;
  133.  
  134. __kernel_exit_and_dispatch:
  135. fclr i ; 割込み禁止
  136. mov.b #0, __kernel_intnest ; ネストカウンタクリア
  137. dispatcher:
  138. mov.w __kernel_schedtsk, a0 ;
  139. mov.w a0, __kernel_runtsk ; schedtsk を runtsk に
  140. .IF MON == 1
  141. ; タスクモニター機能用分岐
  142. ; 不要の場合は (MON = 0)
  143. jsr.a _iana_tsk ; タスク実行情報の設定
  144. mov.w __kernel_runtsk,a0 ; a0を復帰
  145. .ENDIF
  146. jz dispatcher_1 ; schedtsk がなければ割込み待ち
  147. ldc TCB_sp[a0], isp ; タスクスタックポインタを復帰
  148. jmpi.a TCB_pc[a0] ; 実行再開番地へジャンプ
  149. ;
  150. ; schdedtskが NULL の場合は、これより下には行かない
  151. ;
  152. dispatcher_1:
  153. ldc #RAMEND, isp ; 割込み用のスタックへ切替え
  154. inc.b __kernel_intnest ; 非タスクコンテキスト
  155. dispatcher_2:
  156. fset i ; 割込み待ち
  157. wait ; wait命令を使用すると
  158. nop ; 消費電力を抑えることができる.
  159. nop ; コメントをつけたまま(nopのみ)にすると
  160. nop ; アイドルループと同じような動作になる.
  161. nop ;
  162. ;
  163. ; ここで非タスクコンテキスト,割込みスタックに切り換えたのは,
  164. ; ここで発生する割込み処理にどのスタックを使うかという問題の解決と,
  165. ; 割込みハンドラ内でのディスパッチ防止という2つの意味がある.
  166. ;
  167. fclr i ; 割込み禁止
  168. mov.w __kernel_reqflg, r0 ; reqflg が FALSE なら
  169. jz dispatcher_2 ; dispatcher_2 へ
  170. mov.w #0, __kernel_reqflg ; reqflgがTRUEならFALSEにする
  171. dec.b __kernel_intnest ; タスクコンテキストに戻す
  172. jmp.b dispatcher ; dispatcher へ戻る
  173.  
  174.  
  175. ;
  176. ; 割込みハンドラ/CPU例外ハンドラ出口処理
  177. ;
  178. ; 呼出し条件:
  179. ; ・FLGレジスタのIビット=0, IPL=0, タスクコンテキスト(intnest=0)
  180. ; ・使用スタックはタスクスタック, reqflg = TRUE
  181. ;
  182. ret_int:
  183. mov.w #0, __kernel_reqflg ; reqflg <--- FALSE
  184. mov.w __kernel_runtsk, a0 ; A0 <--- runtsk
  185. mov.w __kernel_enadsp, r0 ; enadsp が FALSE なら
  186. jz ret_int_r ; ret_int_r へ
  187. mov.w __kernel_schedtsk, r0 ; schedtskと
  188. cmp.w a0, r0 ; runtsk が同じなら
  189. jeq ret_int_r ; ret_int_r へ
  190. ;;;; (runtsk == NULL) のチェックは必要ないため削除 (07/03/02)
  191. stc isp, TCB_sp[a0] ; タスクスタックを保存
  192. mov.w #(ret_int_r&0ffffh), TCB_pc[a0] ; 実行再開番地を保存
  193. mov.w #(ret_int_r>>16), TCB_pc+2[a0]
  194. jmp.b dispatcher
  195.  
  196. __kernel_break_wait:
  197. ret_int_r:
  198. mov.w TCB_enatex[a0],r0 ; enatex が FALSE ならリターン
  199. btst TCB_enatex_bit,r0
  200. jz ret_int_r_1
  201. mov.w TCB_texptn[a0],r0 ; texptn が 0 ならばリターン
  202. jz ret_int_r_1
  203. jsr.a __kernel_call_texrtn ; タスク例外処理ルーチンの呼出し
  204. ret_int_r_1:
  205. popm r0,r1,r2,r3,a0,a1,sb,fb ; スタックからレジスタを復帰
  206. reit ; タスクへ戻る
  207.  
  208.  
  209. ;
  210. ; 割込み/CPU例外の出入口処理(アセンブリ言語記述部分)
  211. ;
  212. ; 呼出し条件:
  213. ; ・FLGレジスタのIビット=0, IPLは受付けた割込みのIPL.
  214. ; ・スタックは多重割り込みなら割込みスタック, そうでなければ
  215. ; タスクスタック
  216. ; ・a1とa0 には割込み/CPU例外ハンドラのアドレスが格納されている.
  217. ; ・r1 には(タスクor割込み)スタックポインタの値が格納されている.
  218. ; これはそのままCPU例外ハンドラに渡すVP型の変数 p_excinf となる.
  219. ;
  220. ; レジスタがスタック上にどのように保存されているかを以下に示す.
  221. ; この図では上が低位, 下が高位のアドレスで, スタックは下から
  222. ; 上方向に向かって積み上げられるものとする.
  223. ;
  224. ; --------------------------------------
  225. ; | R0(2byte) | <--- p_excinf
  226. ; | |
  227. ; --------------------------------------
  228. ; | R1(2byte) |
  229. ; | |
  230. ; --------------------------------------
  231. ; | R2(2byte) |
  232. ; | |
  233. ; --------------------------------------
  234. ; | R3(2byte) |
  235. ; | |
  236. ; --------------------------------------
  237. ; | A0(2byte) |
  238. ; | |
  239. ; --------------------------------------
  240. ; | A1(2byte) |
  241. ; | |
  242. ; --------------------------------------
  243. ; | SB(2byte) |
  244. ; | |
  245. ; --------------------------------------
  246. ; | FB(2byte) |
  247. ; | |
  248. ; --------------------------------------
  249. ; | PCの下位2バイト |
  250. ; | |
  251. ; --------------------------------------
  252. ; | FLGの下位1バイト |
  253. ; --------------------------------------
  254. ; | FLGの上位4ビット/PCの上位4ビット |
  255. ; --------------------------------------
  256. ;
  257. ; ハンドラからリターンした後は, 多重割込みでなく, かつ reqflg が
  258. ; TRUE になった時に,ret_int へ分岐する.
  259. ;
  260. ; 多重割込みかどうかは割込みネストカウンタの値で判定する.
  261. ; intnest != 0 ならば多重割込みであると判定する.
  262. ;
  263. ; reqflg はCPUロック状態でチェックする. そうでないと,
  264. ; reqflg チェック後に起動された割込みハンドラ内で
  265. ; ディスパッチが要求された場合に,ディスパッチされない.
  266. ;
  267. __kernel_interrupt:
  268. cmp.b #0, __kernel_intnest ; 多重割り込みかどうか
  269. jnz int_from_int ; 0でなければ多重割込み
  270. int_from_task: ; 初段の割込み
  271. ldc #RAMEND, isp ; 割込み用のスタックへ切替える
  272. push.w r1 ; スタックポインタを割込みスタックへ保存
  273. int_from_int: ; 多重割込み
  274. inc.b __kernel_intnest ; ネスト回数をインクリメント
  275. fset i ; 割込み禁止解除
  276. jsri.a a1a0 ; Cルーチン呼び出し
  277. fclr i ; 割込み禁止
  278. dec.b __kernel_intnest ; ネスト回数をデクリメント
  279. jnz int_return ; 多重割り込みならリターン
  280. int_from_task2: ; 初段の割込み
  281. pop.w r1 ; タスクスタックポインタを戻す
  282. ldc r1, isp
  283. ldipl #0 ; タスクのIPL値をセット(IPL=0)
  284. mov.w __kernel_reqflg, r1 ; ディスパッチ要求がないか?
  285. jz int_return ; なければ割込み発生元のタスクに戻る
  286. jmp.b ret_int ; あれば ret_int へジャンプ
  287. int_return:
  288. popm r0,r1,r2,r3,a0,a1,sb,fb ; レジスタ復帰
  289. reit ; 割込み前の処理に戻る
  290.  
  291. ;
  292. ; 微少時間待ち
  293. ;
  294. SIL_DLY_TIM1 .equ 625 ; 最小時間(ループ0回)[ns]
  295. SIL_DLY_TIM2 .equ 250 ; ループ1回あたりの時間[ns]
  296.  
  297. .glb $sil_dly_nse
  298. $sil_dly_nse:
  299. sub.w #SIL_DLY_TIM1, r1
  300. jgtu L0
  301. rts
  302. L0:
  303. sub.w #SIL_DLY_TIM2, r1
  304. jgtu L0
  305. rts
  306.  
  307.  
  308. ; 未使用割込みの処理
  309. .glb _unused_interrupt
  310. _unused_interrupt:
  311. reit
  312.  
  313. .end
Add Comment
Please, Sign In to add comment