source: anotherchoice/tags/jsp-1.4.4-full-UTF8/config/sh1/cpu_support.S@ 363

Last change on this file since 363 was 363, checked in by ykominami, 5 years ago

add tags/jsp-1.4.4-full-UTF8

  • Property svn:executable set to *
File size: 39.6 KB
Line 
1/*
2 * TOPPERS/JSP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2004 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2001-2004 by Industrial Technology Institute,
9 * Miyagi Prefectural Government, JAPAN
10 *
11 * 上記著作権者
12は,以下の (1)〜(4) の条件か,Free Software Foundation
13 * によってå…
14¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
15 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
16 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
17å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
18 * 利用と呼ぶ)することを無償で許諾する.
19 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
20 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
21 * スコード中に含まれていること.
22 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
23 * 用できる形で再é…
24å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
25å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
26 * 者
27マニュアルなど)に,上記の著作権表示,この利用条件および下記
28 * の無保証規定を掲載すること.
29 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
30 * 用できない形で再é…
31å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
32 * と.
33 * (a) 再é…
34å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
35マニュアルなど)に,上記の著
36 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
37 * (b) 再é…
38å¸ƒã®å½¢æ…
39‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
40 * 報告すること.
41 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
42 * 害からも,上記著作権者
43およびTOPPERSプロジェクトをå…
44è²¬ã™ã‚‹ã“と.
45 *
46 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
47お
48 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
49 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
50 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
51 *
52 * @(#) $Id: cpu_support.S,v 1.15 2005/11/07 01:15:43 honda Exp $
53 */
54
55/*
56 * プロセッサ依存モジュール アセンブリ言語部(SH1用)
57 *     カーネル内
58部で使用する定義
59 */
60
61#define _MACRO_ONLY
62#include "jsp_kernel.h"
63#include "offset.h"
64
65/*
66 * タスクコントロールブロックTCB中のsp,pcがå…
67ˆé ­ã‹ã‚‰60バイトの
68 * 範囲内
69にあり、アラインメントが4バイト境界になっていれば、
70 * イミディエイト相対アドレッシングでアクセスできる
71 * TCB_pc,TCB_spはoffset.hで定義されている
72 * (make時に生成される)
73 */
74
75/* イミディエイト相対アドレッシングが可能かチェック */
76#define CHECK_IMMEDIATE_ADDRESSING(dst) \
77 ((dst <= 60) && ((dst % 4) == 0))
78
79#if CHECK_IMMEDIATE_ADDRESSING(TCB_pc) && \
80 CHECK_IMMEDIATE_ADDRESSING(TCB_sp)
81#define TCB_SHORT
82#endif
83
84/*
85 * タスクコントロールブロックTCB中のsp,pcがå…
86ˆé ­ã‹ã‚‰128バイト
87 * 以降にé…
88ç½®ã•ã‚Œã¦ã„ると
89 * mov #TCB_sp,r9
90 * 等の符号拡張を含む命令は期待
91通りに動作しない
92 */
93#if (TCB_pc > 127) || (TCB_sp > 127)
94#error TCB offset is limited 127.
95#endif
96
97#if !CHECK_IMMEDIATE_ADDRESSING(TCB_texptn)
98#error immediate addressing TCB_texptn.
99#endif
100
101/*
102 * その他のオフセット値について
103 *
104 * (1) TCB_enatex
105 * mov.b @(#TCB_enatex,rx),r0命令の即値はゼロ拡張されるので
106 * TCB_enatexに関してはチェックする必
107要がない
108 * (アクセスできる範囲15バイトを超
109えると、アセンブルエラーになる)
110 *
111 * (2) TCB_enatex_mask
112 * and #TCB_enatex_mask,r0命令の即値はゼロ拡張されるので
113 * TCB_enatex_maskに関してはチェックする必
114要がない
115 */
116
117
118/*
119 * タスクディスパッチャ
120 *
121 *  dispatch は、割込み/CPU例外ネストカウンタ = 0,割込み禁止状æ…
122‹
123 * で呼び出さなければならない.exit_and_dispatch も,割込みネスト
124 * カウンタ = 0・割込み禁止状æ…
125‹ã§å‘¼ã³å‡ºã™ã®ãŒåŽŸå‰‡ã§ã‚るが,カーネル
126 * 起動時に対応するため,割込みネストカウンタ = 1で呼び出した場合に
127 * も対応している.
128 */
129
130 .text
131 .align 2
132 .global _dispatch
133_dispatch:
134 /* pr,r8〜r15 をスタックに保存 */
135 mov.l r8, @-r15 /* r0〜r7は呼び出しå…
136ƒã§ä¿å­˜ã—ているため */
137 mov.l r9, @-r15 /* 保存する必
138要が無い */
139 mov.l r10,@-r15
140 mov.l r11,@-r15
141 mov.l r12,@-r15
142 mov.l r13,@-r15
143 mov.l r14,@-r15
144 sts.l pr,@-r15
145#ifdef SAVE_MACL_IN_DISPATCH
146 sts.l mach,@-r15
147 sts.l macl,@-r15
148#endif /* SAVE_MACL_IN_DISPATCH */
149 mov.l _runtsk_dis,r2 /* r0 <- runtsk */
150 mov.l @r2,r0
151 /*
152 * タスクコントロールブロックTCB中のsp,pcがå…
153ˆé ­ã‹ã‚‰60バイトの
154 * 範囲内
155にあり、アラインメントが4バイト境界になっていれば、
156 * イミディエイト相対アドレッシングでアクセスできる
157 */
158#ifdef TCB_SHORT
159 /* タスクスタックポインタを保存 */
160 mov.l r15,@(TCB_sp, r0)
161 mov.l dispatch_r_k,r1 /* 実行再開番地 */
162 bra dispatcher
163 mov.l r1,@(TCB_pc, r0) /* 遅
164延スロット */
165#else /* TCB_SHORT */
166 mov #TCB_sp,r9
167 mov.l r15,@(r0,r9) /* タスクスタックを保存 */
168 mov #TCB_pc,r8
169 mov.l dispatch_r_k,r1 /* 実行再開番地を保存 */
170 bra dispatcher
171 mov.l r1,@(r0,r8) /* 遅
172延スロット */
173#endif /* TCB_SHORT */
174
175 /*
176 * dispatch_r:
177 *  タスクコントコンテキストでディスパッチャ呼び出しをした場合の
178 *  実行再開番地
179 *  dispatcherから呼ばれるので、r7にruntskが代å…
180¥ã•ã‚Œã¦ã„ã‚‹
181 *
182 *   レジスタ割り当て
183 *    r7 :runtsk
184 *    r0 :runtsk->enatex
185 *     mov.b @(imm, r),r0命令はオペランドがr0に
186 *     固定されている
187 *    r1 :runtsk->texptn
188 *    r2 :call_texrtn()のå…
189ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
190 *
191 */
192dispatch_r:
193 /* レジスタを復帰 */
194#ifdef SAVE_MACL_IN_DISPATCH
195 lds.l @r15+,macl
196 lds.l @r15+,mach
197#endif /* SAVE_MACL_IN_DISPATCH */
198 lds.l @r15+,pr
199 mov.l @r15+,r14
200 mov.l @r15+,r13
201 mov.l @r15+,r12
202 mov.l @r15+,r11
203 mov.l @r15+,r10
204 mov.l @r15+,r9
205 mov.l @r15+,r8
206 mov.b @(TCB_enatex,r7),r0 /* オペランドがr0に固定 (c) */
207 mov.l @(TCB_texptn,r7),r1
208 and #TCB_enatex_mask,r0
209 tst r0,r0 /* runtsk->enatexのチェック */
210 bt _dispatch_r_1
211 /* 遅
212延スロットなし */
213 tst r1,r1 /* runtsk->texptnのチェック */
214 bt _dispatch_r_1
215 /* 遅
216延スロットなし */
217 mov.l _call_texrtn_dis,r2 /* タスク例外処理ルーチン起動 */
218 jmp @r2 /*(dispatch()呼び出しå…
219ƒã«ãƒªã‚¿ãƒ¼ãƒ³ã™ã‚‹ï¼‰*/
220 nop /* 遅
221延スロット  */
222_dispatch_r_1:
223 rts /* dispatch()呼び出しå…
224ƒã¸ã®ãƒªã‚¿ãƒ¼ãƒ³ */
225 nop /* 遅
226延スロット  */
227
228
229 .global _exit_and_dispatch
230_exit_and_dispatch:
231 /* 割込みネストカウンタをクリア */
232 mov.l _intnest_dis, r1
233 mov #0,r0
234 mov.l r0,@r1
235
236/*
237 * ディスパッチャ本体
238 *
239 */
240dispatcher:
241 /*
242 * ここには割り込み禁止で来ること
243 */
244 mov.l _schedtsk_dis,r1
245 mov.l _runtsk_dis,r2
246 mov.l @r1,r7 /* r7 <- schedtsk */
247 mov #0, r0 /* (b)       */
248
249 /*
250 * ここでruntskにschedtskを代å…
251¥ã™ã‚‹ã®ã¯ï¼’つの意味がある。
252 *  (1) schedtsk != NULLの場合
253 *     通常のタスク切り替えを行う。
254 *  (2) schedtsk == NULLの場合
255 *     runtskにNULLを代å…
256¥ã—ておく。
257 *     (dispatcher_1以降の割込み待
258ちで割込みがå…
259¥ã‚Šã€ãã®ä¸­ã§
260 *      iget_tid()がコールされたときに正しくTSK_NONEを返すため
261 *      には、実行状æ…
262‹ã®ã‚¿ã‚¹ã‚¯ãŒãªã„時に、runtskをNULLにして
263 *      おく必
264要がある。)
265 */
266 mov.l r7,@r2 /* runtsk←schedtsk  */
267
268 cmp/eq r7,r0 /* schedtsk があるか? (a) 末尾参ç…
269§ */
270 bt dispatcher_1 /* 無ければジャンプ */
271 /* 遅
272延スロットなし */
273
274 /*
275 * タスクコントロールブロックTCBから実行再開番地を取り出して
276 * 分岐する。
277 * 分岐å…
278ˆã¯ä»¥ä¸‹ã®3つ
279 *  dispatch_r:タスクコンテキストからのディスパッチ呼び出し
280 *  ret_int_r :割込みの出口処理
281 *  activate_r:起動直後
282 *
283 *  分岐å…
284ˆã§ã¯r7にruntsk(=schedtsk)がロードされているとして
285 *  使用して良い
286 */
287#ifdef TCB_SHORT
288 /*
289 * タスクコントロールブロックTCB中のsp,pcがå…
290ˆé ­ã‹ã‚‰60バイトの
291 * 範囲内
292にあり、アラインメントが4バイト境界になっていれば、
293 * イミディエイト相対アドレッシングでアクセスできる
294 */
295 /* 実行再開番地を復帰 */
296 mov.l @(TCB_pc, r7),r1
297 jmp @r1
298 mov.l @(TCB_sp, r7),r15 /* 遅
299延スロット */
300 /* タスクスタックポインタを復å…
301ƒ */
302#else /* TCB_SHORT */
303 mov #TCB_pc,r8
304 mov.l @(r7,r8),r1 /* 実行再開番地を復帰 */
305 mov #TCB_sp,r9
306 jmp @r1
307 mov.l @(r7,r9),r15 /* 遅
308延スロット */
309 /* タスクスタックポインタを復å…
310ƒ */
311#endif /* TCB_SHORT */
312
313
314dispatcher_1:
315 /*
316 * ここで割込みモードに切り換えるのは,ここで発生する割込み処理
317 * にどのスタックを使うかという問題の解決と,割込みハンドラ内
318で
319 * のタスクディスパッチの防止という二つの意味がある.
320 */
321
322
323 /* イミディエイト値を毎回読み込むのは効率が悪いので事前に用意する
324 * r0 : 0x00
325 * r1 : 0x01
326 * r8 : 割り込み禁止中のSRの値
327 * r9 : 割り込み許可中のSRの値
328 * r10 : reqflgの番地
329 * r11 : 割込みネストカウンタintnestの番地
330 */
331 mov #0,r0
332 mov #1,r1
333 mov.l _mask_ipm_dis,r8
334
335#ifdef SUPPORT_CHG_IPM
336 mov.l _task_intmask_dis,r2 /* タスクコンテキストのIPM */
337 mov.l @r2,r9
338#else /* SUPPORT_CHG_IPM */
339 mov #0,r9
340#endif /* SUPPORT_CHG_IPM */
341
342 mov.l _reqflg_dis,r10
343 mov.l _intnest_dis,r11
344
345 mov.l _stacktop_dis,r15 /* スタックを割込みスタックに切替え */
346 mov.l r1,@r11 /* 割込みネストカウンタを1にする */
347dispatcher_2:
348 ldc r9,sr /* 割り込み許可 */
349
350 /*
351 * Relase1.4.1で解決された制限事項
352
353 * 
354 * ディスパッチャの出口で実行すべきタスクがない(schedtsk==
355 * NULL)場合は、sleep命令によってプロセッサを省電力モードに切
356 * り替えて割込み待
357ちをしている。
358 * 
359 * 割込み許可後にsleep命令を実行しているため、割込み許可命令の
360 * 実行前に割込み要求がå…
361¥ã£ã¦ã„る場合(あるいは割込み許可直後、
362 * sleep命令実行前に割込み要求がå…
363¥ã£ãŸå ´åˆï¼‰ã€å‰²è¾¼ã¿è¨±å¯å‘½ä»¤ã®
364 * 実行とå…
365±ã«å‰²è¾¼ã¿ãŒå—け付けられ、その復帰後にsleepしたままに
366 * なり、reqflgのチェックに進まない。
367 * (1msec以内
368にタイマ割込みがå…
369¥ã‚‹ãŸã‚ã€å®Ÿéš›ã«ã¯sleepしたままと
370 * いうことはない。)
371 * 
372 * この問題は、割込みの許可とsleep状æ…
373‹ã¸ã®ç§»è¡ŒãŒã‚¢ãƒˆãƒŸãƒƒã‚¯ã«å®Ÿ
374 * 行できないことに起因する。SH3以降ではIPMとは別にSRのBLビット
375 * を使って割込みの禁止/許可を制御することにより、この問題を回
376 * 避できるが、SH1/2ではIPMを設定する以外に割込みを禁止/許可す
377 * る方法がなく、割込み許可(割込み待
378ちのIPM設定)とsleepをアト
379 * ミックに行う方法がない。
380 * そこでSH1依存部では、割込み受付時にスタックに積まれた戻り番
381 * 地を多重割込みの出口処理でチェックし、戻り番地が上記のsleep
382 * 命令に該当する場合は戻り番地を1命令分(2バイト)進めることに
383 * よりこの問題を回避している。
384 * ただし、この方法では多重割込みの出口処理に数命令のオーバー
385 * ヘッドが生じる。
386 * OMIT_POWER_CONTROLマクロを定義することでsleep命令の代わりに
387 * nop命令が挿å…
388¥ã•ã‚Œã€å¤šé‡å‰²è¾¼ã¿ã®å‡ºå£å‡¦ç†ã§ã®ãƒã‚§ãƒƒã‚¯ãƒ«ãƒ¼ãƒãƒ³
389 * は省略される。(この場合は消費電力の点で不利になる。)
390 */
391#ifndef OMIT_POWER_CONTROL
392_waiting_interrupt:
393 sleep /* 割込み待
394ち */
395#else /* OMIT_POWER_CONTROL */
396 nop
397#endif /* OMIT_POWER_CONTROL */
398 ldc r8,sr /* 割り込み禁止 */
399 mov.l @r10,r2 /* reqflgのチェック */
400 tst r2,r2 /* FALSEならば、もう1度割り込み待
401ち */
402 bt dispatcher_2
403 /* 遅
404延スロットなし */
405 mov.l r0,@r10 /* reqflgのクリア */
406 bra dispatcher
407 mov.l r0,@r11 /* 遅
408延スロット */
409 /* 割込みネストカウンタをクリア */
410
411 /*
412 * 割込み待
413ちの直前に行ったスタック切替の戻しを行っていないが、
414 * ディスパッチャの出口でTCBから取り出した値をスタックポイン
415 * タに設定するので問題ない。
416 */
417
418
419 .align 2
420_runtsk_dis:
421 .long _runtsk
422_schedtsk_dis:
423 .long _schedtsk
424_call_texrtn_dis:
425 .long _call_texrtn
426_mask_ipm_dis:
427 .long MAX_IPM << 4 /* 割込み禁止時のSRの値 */
428dispatch_r_k:
429 .long dispatch_r
430_stacktop_dis:
431 .long STACKTOP /* タスク独立部のスタックの初期値 */
432
433_intnest_dis: /* 割込み/CPU例外ネストカウンタ */
434 .long _intnest
435_reqflg_dis:
436 .long _reqflg
437
438#ifdef SUPPORT_CHG_IPM
439_task_intmask_dis: /* タスクコンテキストの割込みマスク */
440 .long _task_intmask
441#endif /* SUPPORT_CHG_IPM */
442
443
444/*
445 * 割込み/CPU例外のå…
446¥å£å‡¦ç†
447 */
448
449/*
450 * gccのメジャーバージョンによる動作の切替
451 *    
452 *   gcc2.x:割込みの出口でタスクスイッチするときのみ、
453 *       macレジスタを保存/退避する
454 *   gcc3.x以降:割込みの出å…
455¥å£ã§macレジスタを保存/退避する
456 *       (タスクスイッチの有無に依らない)
457 *    
458 *   これにより、スタックå…
459ˆé ­ã‹ã‚‰PC,SRへのオフセットが異なるので
460 *   注意。
461 */
462#if defined(__GNUC__) && (__GNUC__ > 2)
463#define SAVE_MACL_BEFORE_INTERRUPT_HANDLER
464#define SAVE_MACL_IN_DISPATCH
465#endif /* __GNUC__ */
466
467/*
468 * 割込み/CPU例外の際のスタックポインタが指し示す位置から
469 * SR,PCのコピーがある場所までのオフセット
470 *    
471 *   ここでいうスタックポインタとは割込み/CPU例外のå…
472¥å£å‡¦ç†ã§
473 *   プロシージャレジスタPRの退避が終わった直後の値を意味する。
474 *   SRはスタックå…
475ˆé ­ã‹ã‚‰40バイト下に、PCは36バイト下に積まれて
476 *   いる。  (ret_int_3を参ç…
477§ï¼‰
478 */
479#ifdef SAVE_MACL_BEFORE_INTERRUPT_HANDLER
480#define SP_SR_OFFSET (40+8)
481#define SP_PC_OFFSET (36+8)
482#else /* SAVE_MACL_BEFORE_INTERRUPT_HANDLER */
483#define SP_SR_OFFSET 40
484#define SP_PC_OFFSET 36
485#endif /* SAVE_MACL_BEFORE_INTERRUPT_HANDLER */
486
487/*
488 * CPU例外のå…
489¥å£å‡¦ç†ã®ç¶šã
490 *
491 * CPU例外ハンドラは,非タスクコンテキストで実行する.そのため,CPU例
492 * 外ハンドラを呼び出す前に割込みモードに移行し,リターンしてきた後に
493 * å…
494ƒã®ãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã™ï¼Žå…
495ƒã®ãƒ¢ãƒ¼ãƒ‰ã«æˆ»ã™ãŸã‚ã«ï¼Œå‰²è¾¼ã¿ãƒ¢ãƒ¼ãƒ‰ã«ç§»è¡Œã™ã‚‹å‰
496 * の SR を割込みスタック上に保存する.CPU例外がタスクコンテキストで
497 * 発生し,reqflg が TRUE になった時に,ret_exc へ分岐する.
498 * reqflg をチェックする前に割込みを禁止しないと,reqflg をチェック後
499 * に起動された割込みハンドラ内
500でディスパッチが要求された場合に,ディ
501 * スパッチされない.
502 *  
503 * 一般不当命令の場合は戻り番地を2バイト進める必
504要があるが
505 * 対応していない
506 * (GDB stubがブレークポイントとして使用する。)
507 *  
508 *   CPU例外要因毎に展開されるルーチンでr0,r1を保存し、
509 *   割込み禁止にした後、
510 *    r1:割込み受付直後のSRのコピー
511 *    r2:C言語ルーチンのå…
512ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
513 *   の状æ…
514‹ã§ã“こに来る。
515 *   
516 *   レジスタ割当
517 *    r4:C言語ルーチンの引数
518 *      スタック上に積まれたSRのアドレス
519 *    r7:タスクスタックポインタ
520 */
521 .text
522 .align 2
523 .globl _cpu_exception_entry
524_cpu_exception_entry:
525 /* 残りのスクラッチレジスタをスタックに積む  */
526 mov.l r3,@-r15
527 mov.l r4,@-r15
528 mov.l r5,@-r15
529 mov.l r6,@-r15
530 mov.l r7,@-r15
531 sts.l pr,@-r15
532 mov r15,r4 /* C言語ルーチンの引数設定 */
533 add #SP_SR_OFFSET, r4
534 /* 割込み/CPU例外ネストカウンタのチェック */
535 mov.l _intnest_int, r5
536 mov.l @r5,r6
537 tst r6,r6 /* CPU例外発生時のコンテキストを判定 */
538 add #0x1,r6 /* 割込みネストカウンタをインクリメント */
539 /* add命令ではsrのTビットは変化しない */
540 mov.l r6,@r5
541 /* 多重例外ならジャンプ */
542 bf _exc_from_int
543 /* 遅
544延スロットなし */
545
546/* 初段のCPU例外の場合 */
547 /* スタックå…
548¥ã‚Œæ›¿ãˆå‰ã® */
549 /* タスクスタックポインタを保存 */
550 mov r15,r7
551 /* 割込みスタックに切り替え */
552 mov.l _stacktop_int,r15
553 ldc r1,sr /* 割込み許可 */
554 jsr @r2 /* C言語ルーチン呼び出し */
555 mov.l r7,@-r15 /* 遅
556延スロット  */
557 /* タスクスタックポインタを */
558 /* 割込みスタックに積む */
559
560 /* 割込み禁止 */
561 mov.l _mask_ipm_int,r0
562 ldc r0,sr
563 /* 割込み/CPU例外ネストカウンタをクリア */
564 mov.l _intnest_int,r0
565 mov #0x0,r1
566 mov.l r1,@r0
567 mov.l @r15,r15 /* スタック切替え */
568 /* reqflgのチェック */
569 mov.l _reqflg_int,r4
570 mov.l @r4,r5
571 tst r5,r5
572 bt 1f /* reqflg=FALSEの場合はret_to_task_excへ */
573 /* 遅
574延スロットなし */
575 bra ret_exc /* reqflg=TRUEの場合はret_excへ */
576 nop /* 遅
577延スロット */
578
579 /*
580 * bt命令ではret_to_task_excに届かないので、bra命令を1クッション
581 * å…
582¥ã‚Œã‚‹ã€‚
583 */
5841:
585 bra ret_to_task_exc /* reqflg=FALSEの場合 */
586 nop /* 遅
587延スロット */
588
589
590/* 多重CPU例外の場合 */
591/* CPU例外発生時のコンテキストを判別後、 */
592/* 割込み禁止 */
593/* r1:割込み受付時のsrのコピー */
594/* r2:C言語ルーチンのå…
595ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ */
596/* r4:C言語ルーチンの引数 */
597/* の状æ…
598‹ã§ã“こに飛んでくる */
599/* C言語ルーチンの引数設定と割込みネストカウンタの */
600/* インクリメントは済んでいる */
601
602_exc_from_int:
603 jsr @r2 /* C言語ルーチン呼び出し */
604 ldc r1,sr /* 割込み許可(遅
605延スロット) */
606
607 mov.l _mask_ipm_int,r0 /* 割込み禁止 */
608 ldc r0,sr
609 /* 割込み/CPU例外ネストカウンタをディクリメント */
610 mov.l _intnest_int,r3
611 mov.l @r3,r4
612 add #-1,r4
613 bra _ret_to_exc
614 mov.l r4,@r3 /* 遅
615延スロット */
616
617
618/*
619 * 割込みの口処理の続き
620 *
621 *   割込み要因毎に展開されるルーチンでr0,r1を保存し、
622 *   割込み禁止にした後、
623 *    r1:割込み受付直後のSRのコピー
624 *    r2:C言語ルーチンのå…
625ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹
626 *   の状æ…
627‹ã§ã“こに来る。
628 *   
629 *   レジスタ割当
630 *    r7:タスクスタックポインタ
631 */
632 .text
633 .align 2
634 .globl _interrupt_entry
635_interrupt_entry:
636 /* 残りのスクラッチレジスタをスタックに積む  */
637 mov.l r3,@-r15
638 mov.l r4,@-r15
639 mov.l r5,@-r15
640 mov.l r6,@-r15
641 mov.l r7,@-r15
642 sts.l pr,@-r15
643#ifdef SAVE_MACL_BEFORE_INTERRUPT_HANDLER
644 sts.l mach,@-r15
645 sts.l macl,@-r15
646#endif /* SAVE_MACL_BEFORE_INTERRUPT_HANDLER */
647
648 /* 割込み/CPU例外ネストカウンタのチェック */
649 mov.l _intnest_int, r5
650 mov.l @r5,r6
651 tst r6,r6 /* 割込み発生時のコンテキストを判定 */
652 add #0x1,r6 /* 割込みネストカウンタをインクリメント */
653 /* add命令ではsrのTビットは変化しない */
654 mov.l r6,@r5
655 /* 多重割込みならジャンプ */
656 bf _interrupt_from_int
657 /* 遅
658延スロットなし */
659
660/* 初段の割込みの場合 */
661 /* スタックå…
662¥ã‚Œæ›¿ãˆå‰ã® */
663 /* タスクスタックポインタを保存 */
664 mov r15,r7
665 /* 割込みスタックに切り替え */
666 mov.l _stacktop_int,r15
667 ldc r1,sr /* 割込み許可 */
668 jsr @r2 /* C言語ルーチン呼び出し */
669 mov.l r7,@-r15 /* 遅
670延スロット  */
671 /* タスクスタックポインタを */
672 /* 割込みスタックに積む */
673
674 /* 割込み禁止 */
675 mov.l _mask_ipm_int,r0
676 ldc r0,sr
677 /* 割込み/CPU例外ネストカウンタをクリア*/
678 mov.l _intnest_int,r0
679 mov #0x0,r1
680 mov.l r1,@r0
681 mov.l @r15,r15 /* スタック切替え */
682 /* reqflgのチェック */
683 mov.l _reqflg_int,r4
684 mov.l @r4,r5
685 tst r5,r5
686 bt ret_to_task_int /* reqflg=FALSEの場合 */
687 /* 遅
688延スロットなし */
689 bra ret_int /* reqflg=TRUEの場合 */
690 nop /* 遅
691延スロット */
692
693
694/* 多重割込みの場合 */
695/* 割込み発生時のコンテキストを判別後、 */
696/* 割込み禁止 */
697/* r1:割込み受付時のsrのコピー */
698/* r2:C言語ルーチンのå…
699ˆé ­ã‚¢ãƒ‰ãƒ¬ã‚¹ */
700/* の状æ…
701‹ã§ã“こに飛んでくる */
702/* (割込みネストカウンタのインクリメントは済んでいる) */
703
704_interrupt_from_int:
705 jsr @r2 /* C言語ルーチン呼び出し */
706 ldc r1,sr /* 割込み許可(遅
707延スロット) */
708
709 mov.l _mask_ipm_int,r0 /* 割込み禁止 */
710 ldc r0,sr
711 /* 割込み/CPU例外ネストカウンタをディクリメント */
712 mov.l _intnest_int,r3
713 mov.l @r3,r4
714 add #-1,r4
715 mov.l r4,@r3
716
717
718/* 多重割込み/CPU例外からの復帰処理
719 *
720 * ・ディスパッチもタスク例外処理も必
721要ない
722 * ・chg_ipm()の処理は必
723要ない
724 *  (非タスクコンテキストでは、chg_ipm()は使用不可)
725 *
726 *
727 * ディスパッチャの出口で実行すべきタスクがない(schedtsk==NULL)場合
728 * は、sleep命令によってプロセッサを省電力モードに切り替えて割込み待
729
730 * ちをしている。(dispatcher_2付近を参ç…
731§ï¼‰
732 *
733 * 割込み許可後にsleep命令を実行しているため、割込み許可命令の実行前
734 * に割込み要求がå…
735¥ã£ã¦ã„る場合(あるいは割込み許可直後、sleep命令実
736 * 行前に割込み要求がå…
737¥ã£ãŸå ´åˆï¼‰ã€å‰²è¾¼ã¿è¨±å¯å‘½ä»¤ã®å®Ÿè¡Œã¨å…
738±ã«å‰²è¾¼ã¿ãŒ
739 * 受け付けられ、その復帰後にsleepしたままになってしまう。
740 * (reqflgのチェックに進まない。)この問題は、割込みの許可とsleep 状
741 * æ…
742‹ã¸ã®ç§»è¡ŒãŒã‚¢ãƒˆãƒŸãƒƒã‚¯ã«å®Ÿè¡Œã§ããªã„ことに起因する。
743 * これを防ぐため、割込みの出口で戻りå…
744ˆã‚¢ãƒ‰ãƒ¬ã‚¹ãŒå•é¡Œã®sleep命令であ
745 * る場合、戻り番地を1命令分進める処理をしている。(実行すべきタスク
746 * がなく、ディスパッテャ内
747で割込み待
748ち中に割込みを受け付けた場合は、
749 * ディスパッチャの二重呼び出しを避けるため、多重割込みとして処理して
750 * いるため、下記の_ret_to_intを通過する。
751 */
752_ret_to_int:
753_ret_to_exc:
754
755#ifndef OMIT_POWER_CONTROL
756 /* r4←スタック上に積まれた戻り番地 */
757 mov.l @(SP_PC_OFFSET, r15), r4
758 mov.l _waiting_interrupt_int, r5
759 cmp/eq r4, r5
760 bf _ret_to_int_1
761 add #2, r4
762 mov.l r4, @(SP_PC_OFFSET, r15)
763#endif /* OMIT_POWER_CONTROL */
764
765_ret_to_int_1:
766 /* レジスタ復å…
767ƒ */
768#ifdef SAVE_MACL_BEFORE_INTERRUPT_HANDLER
769 lds.l @r15+,macl
770 lds.l @r15+,mach
771#endif /* SAVE_MACL_BEFORE_INTERRUPT_HANDLER */
772 lds.l @r15+,pr
773 mov.l @r15+,r7
774 mov.l @r15+,r6
775 mov.l @r15+,r5
776 mov.l @r15+,r4
777 mov.l @r15+,r3
778 mov.l @r15+,r2
779 mov.l @r15+,r1
780 mov.l @r15+,r0
781 rte /* 割込みå…
782ƒã«æˆ»ã‚‹ */
783 nop
784
785 .align 2
786_stacktop_int: /* タスク独立部のスタックの初期値 */
787 .long STACKTOP
788_intnest_int: /* 割込み/CPU例外ネストカウンタ */
789 .long _intnest
790_reqflg_int:
791 .long _reqflg
792_mask_ipm_int: /* 割込み禁止用マスク */
793 .long MAX_IPM << 4 /* ipm以外のビットはゼロで良い */
794
795#ifndef OMIT_POWER_CONTROL
796_waiting_interrupt_int:
797 .long _waiting_interrupt
798#endif /* OMIT_POWER_CONTROL */
799
800/*
801 * 割込みハンドラ/CPU例外ハンドラ出口処理
802 *
803 * 戻りå…
804ˆãŒã‚¿ã‚¹ã‚¯ã§reqflgがセットされている場合のみここにくる。
805 * 割込みネストカウンタ = 0,割込み禁止状æ…
806‹,スクラッチレジスタを
807 * 保存した状æ…
808‹ã§å‘¼ã³å‡ºã™ã“と。
809 *
810 * r4には変数reqflgのアドレスが代å…
811¥ã•ã‚ŒãŸçŠ¶æ…
812‹ã§ã“こに来る。
813 *
814 */
815 .text
816 .align 2
817ret_int:
818ret_exc:
819 /*
820 * 戻りå…
821ˆãŒå‰²è¾¼ã¿ã®å…
822¥å£å‡¦ç†ã‹å¦ã‹ã®åˆ¤åˆ¥
823 * 
824 * SH1では割込み受付直後に割込み禁止になっていないため、割込みA
825 * のå…
826¥å£å‡¦ç†ä¸­ã«åˆ¥ã®å‰²è¾¼ã¿Bがå…
827¥ã‚‹å¯èƒ½æ€§ãŒã‚る。(これはハード
828 * ウェアのアーキテクチャ上避けようがない。)割込みハンドラB内
829
830 * でタスク切り替えを起こすようなサービスコールを呼ぶと割込みB
831 * の出口処理で別のタスクにディスパッチしてしまい、タスク2から
832 * å…
833ƒã®ã‚¿ã‚¹ã‚¯ã«æˆ»ã£ã¦ãã‚‹ã¾ã§ã€å‰²è¾¼ã¿Aの処理が遅
834れてしまう。
835 * また、割込みAがレベルトリガだと2回検出されてしまう問題もある。
836 * これを防ぐため、スタックに積んである戻りå…
837ˆã®IPMとtask_intmask
838 * の値を比較して、å…
839¥å£å‡¦ç†ä¸­ã«å‰²è¾¼ã¿ãŒå…
840¥ã‚‰ãªã‹ã£ãŸã‹ãƒã‚§ãƒƒã‚¯ã—
841 * ている。ディスパッチする前のタイミングで判別しているので、
842 * chg_ipm()でtask_intmaskが書き換えられている心é…
843ã¯ãªã„。
844 */
845 /* r0←スタックに積まれたsr */
846 mov.l @(SP_SR_OFFSET,r15),r0
847#ifdef SUPPORT_CHG_IPM
848 mov.l _task_intmask_ret,r2 /* r2←&task_intmask */
849 and #0xf0, r0 /* IPM取り出し */
850 mov.l @r2,r3 /* r3←task_intmask */
851 cmp/eq r0, r3 /* 戻りå…
852ˆãŒå‰²è¾¼ã¿ã®å…
853¥å£å‡¦ç†ã‹ï¼Ÿ */
854#else /* SUPPORT_CHG_IPM */
855 /*
856 * chg_ipmをサポートしない場合は、タスクコンテキストのIPMは
857 * 常に0x0
858 */
859 and #0xf0, r0 /* IPM取り出し */
860 cmp/eq #0x00, r0 /* 戻りå…
861ˆãŒå‰²è¾¼ã¿ã®å…
862¥å£å‡¦ç†ã‹ï¼Ÿ */
863#endif /* SUPPORT_CHG_IPM */
864 bf ret_to_task_int /* ディスパッチしないで割込みå…
865ƒã« */
866 /* 戻る処理へ */
867 /* 遅
868延スロットなし */
869
870#ifdef SUPPORT_CPU_EXC_ENTRY_CHECK
871 /*
872 * 戻りå…
873ˆãŒCPU例外のå…
874¥å£å‡¦ç†ã‹å¦ã‹ã®åˆ¤åˆ¥
875 * 
876 * SH1ではCPU例外も割込みとほぼ同じ出å…
877¥å£å‡¦ç†ã‚’行っているが、
878 * CPU例外を受け付けても割込みマスクは変化しない。CPU例外のå…
879¥
880 * 口処理中に割込みがå…
881¥ã£ãŸå ´åˆã«å‚™ãˆã¦ã€ã‚¹ã‚¿ãƒƒã‚¯ä¸Šã«ç©ã¾ã‚ŒãŸ
882 * 戻り番地を使って判別を行う。
883 * 
884 * 
885 *  check_exc_entry()のAPI
886 *   引数r4:スタック上に積まれた戻り番地
887 *   戻り値r0:
888 *     1:戻りå…
889ˆãŒCPU例外のå…
890¥å£å‡¦ç†
891 *     0:それ以外
892 */
893 mov.l _check_exc_entry_ret, r1
894 jsr @r1 /* C言語ルーチン呼び出し */
895 mov.l @(SP_PC_OFFSET, r15), r4 /* 引数設定(遅
896延スロット) */
897
898 tst r0, r0 /* 戻り値の判定 */
899 bf ret_to_task_int /* 戻りå…
900ˆãŒCPU例外のå…
901¥å£å‡¦ç†ã§ã‚れば */
902 /*  ディスパッチしないで割込みå…
903ƒã«æˆ»ã‚‹ */
904 /* 遅
905延スロットなし */
906
907#endif /* SUPPORT_CPU_EXC_ENTRY_CHECK */
908
909 /*
910 * reqflgのクリア
911 * 
912 * ここに到達する前にreqflgをクリアしてしまうと、上記の割込みA
913 * の出口処理でディスパッチャ呼び出しが必
914要なケースでもディス
915 * パッチャが呼び出されない。
916 * (割込みBでreqflgをセットして、割込みAでreqflgに変化がない場
917 *  合)
918 */
919 mov #0x0, r0
920 mov.l _reqflg_ret,r1
921 mov.l r0, @r1 /* reqflg <- 0 */
922
923 mov.l _runtsk_ret,r1 /* r7 <- runtsk */
924 mov.l @r1,r7
925 mov.l _enadsp_ret,r2 /* enadspのチェック */
926 mov.l @r2,r3
927 tst r3,r3 /* ディスパッチ禁止ならret_int_1へ */
928 bt ret_int_1
929 /* 遅
930延スロットなし */
931
932 mov.l _schedtsk_ret,r4 /* r5 <- schedtsk */
933 mov.l @r4,r5
934 cmp/eq r7,r5 /* runtsk と schedtsk を比較 */
935 bt ret_int_1 /* 同じならret_int_1へ */
936 /* 遅
937延スロットなし */
938
939 mov.l r8,@-r15 /* 残りのレジスタを保存 */
940 mov.l r9,@-r15
941 mov.l r10,@-r15
942 mov.l r11,@-r15
943 mov.l r12,@-r15
944 mov.l r13,@-r15
945 mov.l r14,@-r15
946#ifndef SAVE_MACL_BEFORE_INTERRUPT_HANDLER
947 /*
948 * タスクスイッチするときのみ、
949 * macレジスタを保存する
950 */
951 sts.l mach,@-r15
952 sts.l macl,@-r15
953#endif /* SAVE_MACL_BEFORE_INTERRUPT_HANDLER */
954 stc.l gbr,@-r15
955 /*
956 * タスクコントロールブロックTCB中のsp,pcがå…
957ˆé ­ã‹ã‚‰60バイトの
958 * 範囲内
959にあり、アラインメントが4バイト境界になっていれば、
960 * イミディエイト相対アドレッシングでアクセスできる
961 */
962#ifdef TCB_SHORT
963 /* タスクスタックポインタを保存 */
964 mov.l r15,@(TCB_sp, r7)
965 mov.l ret_int_r_ret,r1 /* 実行再開番地 */
966 bra dispatcher
967 mov.l r1,@(TCB_pc, r7) /* 遅
968延スロット */
969
970#else /* TCB_SHORT */
971 mov #TCB_sp,r1 /* タスクスタックを保存 */
972 mov.l r15,@(r7,r1)
973 mov.l ret_int_r_ret,r1 /* 実行再開番地を保存 */
974 mov #TCB_pc,r2 /* ディスパッチャからの戻りå…
975ˆã‚’ */
976 /* ret_int_rに設定  */
977 bra dispatcher
978 mov.l r1,@(r7,r2) /* 遅
979延スロット */
980#endif /* TCB_SHORT */
981
982/*
983 * 割込みの出口でディスパッチャからここに戻ってくる
984 * r7にruntskが代å…
985¥ã•ã‚ŒãŸçŠ¶æ…
986‹ã§ã“こに来る
987 */
988ret_int_r:
989 ldc.l @r15+,gbr /* レジスタを復帰 */
990#ifndef SAVE_MACL_BEFORE_INTERRUPT_HANDLER
991 lds.l @r15+,macl
992 lds.l @r15+,mach
993#endif /* SAVE_MACL_BEFORE_INTERRUPT_HANDLER */
994 mov.l @r15+,r14
995 mov.l @r15+,r13
996 mov.l @r15+,r12
997 mov.l @r15+,r11
998 mov.l @r15+,r10
999 mov.l @r15+,r9
1000 mov.l @r15+,r8
1001
1002 /*
1003 * ディスパッチャからret_int_rに分岐した場合、
1004 * ret_intから直接ここに分岐した場合、
1005 * いずれの場合も、r7にruntskが代å…
1006¥ã•ã‚Œã¦ã„ã‚‹
1007 *
1008 *  レジスタ割り当て
1009 * r7 : runtsk
1010 * r0 : runtsk->enatex
1011 *     mov.b @(imm, r),r0命令はオペランドがr0に
1012 *     固定されている
1013 * r2 : runtsk->texptn
1014 * r3 : call_texrtn()のå…
1015ˆé ­ç•ªåœ°
1016 */
1017ret_int_1:
1018 mov.b @(TCB_enatex,r7),r0 /* オペランドがr0に固定 (d) */
1019 and #TCB_enatex_mask,r0
1020 tst r0,r0 /* runtsk->enatexのチェック */
1021 bt ret_int_2
1022 /* 遅
1023延スロットなし */
1024 mov.l @(TCB_texptn,r7),r2 /* runtsk->texptnのチェック */
1025 tst r2,r2
1026 bt ret_int_2
1027 /* 遅
1028延スロットなし */
1029 mov.l _call_texrtn_ret,r3 /* タスク例外処理ルーチン起動 */
1030 jsr @r3
1031 nop /* 遅
1032延スロット */
1033
1034ret_int_2:
1035#ifdef SUPPORT_CHG_IPM
1036 /*
1037 * SH1では割込みからのリターン命令でハードウェアがスタック上
1038 * のデータを読み出してSRを復å…
1039ƒã™ã‚‹ã€‚
1040 * 割込みによって別のタスクに切り替わった場合は、タスクコンテ
1041 * キストのIPMが変更されている可能性があるのでスタック上のSR
1042 * のコピーに含まれるIPMを更新しておく必
1043要がある。
1044 */
1045 /* r0←スタックに積まれたsr */
1046 mov.l @(SP_SR_OFFSET,r15),r0
1047 mov.l _unmask_ipm_ret,r1
1048 mov.l _task_intmask_ret,r2 /* r2←&task_intmask */
1049 and r1,r0 /* IPMビットをクリア */
1050 mov.l @r2,r3 /* r3←task_intmask */
1051 or r3,r0 /* IPMビットをセット */
1052 /* スタックに積んであるsrに上書き */
1053 mov.l r0,@(SP_SR_OFFSET,r15)
1054#endif /* SUPPORT_CHG_IPM */
1055
1056 /*
1057 * タスクへの復帰処理
1058 *  ディスパッチャ呼び出しが要らない場合はここから合流する。
1059 *  å…
1060¥å£å‡¦ç†ã®é€”中で割込みがå…
1061¥ã£ãŸå ´åˆã¯ã€å…
1062¥å£å‡¦ç†ãŒæˆ»ã‚Šå…
1063ˆã«
1064 *  なる。
1065 */
1066ret_to_task_int:
1067ret_to_task_exc:
1068 /* pr,スクラッチレジスタを復帰 */
1069 /* スタックのå…
1070ˆé ­ã‹ã‚‰ã®ã‚ªãƒ•ã‚»ãƒƒãƒˆ */
1071#ifdef SAVE_MACL_BEFORE_INTERRUPT_HANDLER
1072 lds.l @r15+,macl /* +0:MACL */
1073 lds.l @r15+,mach /* +4:MACH */
1074#endif /* SAVE_MACL_BEFORE_INTERRUPT_HANDLER */
1075 lds.l @r15+,pr /* +0:PR */
1076 mov.l @r15+,r7 /* +4:r7 */
1077 mov.l @r15+,r6 /* +8:r6 */
1078 mov.l @r15+,r5 /* +12:r5 */
1079 mov.l @r15+,r4 /* +16:r4 */
1080 mov.l @r15+,r3 /* +20:r3 */
1081 mov.l @r15+,r2 /* +24:r2 */
1082 mov.l @r15+,r1 /* +28:r1 */
1083 mov.l @r15+,r0 /* +32:r0 */
1084 /* +36:PC */
1085 /* +40:SR */
1086 rte
1087 nop /* 遅
1088延スロット */
1089 .align 4
1090_reqflg_ret:
1091 .long _reqflg
1092_call_texrtn_ret:
1093 .long _call_texrtn
1094_runtsk_ret:
1095 .long _runtsk
1096_schedtsk_ret:
1097 .long _schedtsk
1098_enadsp_ret:
1099 .long _enadsp
1100ret_int_r_ret:
1101 .long ret_int_r
1102
1103#ifdef SUPPORT_CHG_IPM /* chg_ipm()をサポートする場合 */
1104_unmask_ipm_ret:
1105 .long ~0xf0 /* ipmビット以外すべて1 */
1106_task_intmask_ret:
1107 .long _task_intmask
1108#endif /* SUPPORT_CHG_IPM */
1109
1110#ifdef SUPPORT_CPU_EXC_ENTRY_CHECK
1111_check_exc_entry_ret:
1112 .long _check_cpu_exc_entry
1113#endif /* SUPPORT_CPU_EXC_ENTRY_CHECK */
1114
1115
1116/*
1117 * no_reg_exception()
1118 * CPU例外として登録されていない例外が発生すると呼び出される
1119 * 例外が発生した時点のpc,sr,pr,r0〜15を出力してカーネル
1120 * を停止する。
1121 */
1122 .text
1123 .align 2
1124 .globl _no_reg_exception
1125_no_reg_exception:
1126 /* pr,r0〜15を保存 */
1127 sts.l pr, @-r15
1128 mov.l r15,@-r15
1129 mov.l r14,@-r15
1130 mov.l r13,@-r15
1131 mov.l r12,@-r15
1132 mov.l r11,@-r15
1133 mov.l r10,@-r15
1134 mov.l r9, @-r15
1135 mov.l r8, @-r15
1136 mov.l r7, @-r15
1137 mov.l r6, @-r15
1138 mov.l r5, @-r15
1139 mov.l r4, @-r15
1140 mov.l r3, @-r15
1141 mov.l r2, @-r15
1142 mov.l r1, @-r15
1143 mov.l r0, @-r15
1144
1145 /* cpu_experr()の呼び出し */
1146 mov.l _cpu_experr_k,r1 /* (cpu_config.c) */
1147 jsr @r1
1148 mov r15, r4 /* 引数設定(遅
1149延スロット) */
1150
1151 .align 2
1152_cpu_experr_k:
1153 .long _cpu_experr
1154
1155
1156
1157/* イミディエイト相対アドレッシングが可能かチェック */
1158#if !(CHECK_IMMEDIATE_ADDRESSING(TCB_tinib) \
1159 && CHECK_IMMEDIATE_ADDRESSING(TINIB_task) \
1160 && CHECK_IMMEDIATE_ADDRESSING(TINIB_exinf) )
1161
1162ここでアセンブル・エラー
1163#endif
1164
1165
1166/*
1167 * タスク起動処理
1168 *   dispatcherから呼ばれるので、r7にruntskが代å…
1169¥ã•ã‚Œã¦ã„ã‚‹
1170 *
1171 */
1172 .text
1173 .align 2
1174 .globl _activate_r
1175_activate_r:
1176 /* 割り込み許可の準備 */
1177#ifndef SUPPORT_CHG_IPM /* (t_unlock_cpu相当の処理) */
1178 mov #0,r1 /* IPM以外のビットも破壊される */
1179#else /* SUPPORT_CHG_IPM */
1180 mov.l _task_intmask_act,r2
1181 mov.l @r2,r1
1182#endif /* SUPPORT_CHG_IPM */
1183 ldc r1,sr /* 割込み許可 */
1184 mov.l _ext_tsk_act,r3
1185 lds r3,pr /* タスクからの戻り番地を設定 */
1186
1187 /*
1188 * ここで割込みがå…
1189¥ã£ã¦runtskが書き換わっても、
1190 * このタスクに戻ってくるときにはruntskの値も
1191 * 当然、å…
1192ƒã«æˆ»ã£ã¦ã„ã‚‹
1193 *
1194 * レジスタ割り当て
1195 *   r7:runtsk
1196 *   r1:&(runtsk->tinib)
1197 *   r2:runtsk->tinib->task
1198 *   r4:タスクの拡張情
1199報(引数)
1200 */
1201 mov.l @(TCB_tinib,r7),r1
1202 mov.l @(TINIB_task,r1),r2 /* タスク起動番地 */
1203 jmp @r2 /* jsr命令ではprを破壊してしまう*/
1204 mov.l @(TINIB_exinf,r1),r4 /* 遅
1205延スロット */
1206 /* 拡張情
1207報(タスクへの引数) */
1208 .align 2
1209_ext_tsk_act:
1210 .long _ext_tsk
1211
1212#ifdef SUPPORT_CHG_IPM
1213_task_intmask_act:
1214 .long _task_intmask
1215#endif /* SUPPORT_CHG_IPM */
1216
1217/*
1218 * 微少時間待
1219ち
1220 */
1221 .globl _sil_dly_nse
1222_sil_dly_nse:
1223
1224 mov.l _sil_dly_tim1, r1 /* r4から SIL_DLY_TIM1 を引く */
1225 add r1, r4
1226 cmp/pl r4 /* 結果が 0 以下ならリターン */
1227 bt _sil_dly_nse1
1228 /* 遅
1229延スロットなし */
1230 rts
1231 nop
1232_sil_dly_nse1:
1233 mov.l _sil_dly_tim2, r1 /* r4から SIL_DLY_TIM2 を引く */
1234 add r1, r4
1235 cmp/pl r4 /* 結果が 0 以下ならリターン */
1236 bt _sil_dly_nse1
1237 /* 遅
1238延スロットなし */
1239 rts
1240 nop
1241 .align 2
1242_sil_dly_tim1:
1243 .long -SIL_DLY_TIM1
1244_sil_dly_tim2:
1245 .long -SIL_DLY_TIM2
1246
1247
1248/*
1249 * 備忘録
1250 *   dispatcher内
1251(a)行でcmp/eq imm,r0命令を使わない理由
1252 *   
1253 *   dispatcherでr7にruntskの値を代å…
1254¥ã—、分岐å…
1255ˆã®dispatch_r、
1256 *   ret_int_r、activate_rでは無駄なロードをしないようにしてい
1257 *   る。
1258 *   schedtskの有無をチェックするときのcmp/eq imm,r0命令((a)
1259 *   行)がオペランドをr0に固定されているため、それに合わせて、
1260 *   最初はruntskにr0を割り当てていた。
1261 *   しかし、r0は各分岐å…
1262ˆã«ã‚ã‚‹enatexの読み出し(c),(d)行のmov.b
1263 *   命令でも予約しているため、できれば空けておきたい。
1264 *   (mov.b @(imm, r),r0命令はオペランドがr0に固定されている。)
1265 *   従って、runtskはr7に割り当て、(a)行はcmp/eq imm,r0命令から
1266 *   cmp/eq rn,rm命令に変更した。そのため、レジスタに0を代å…
1267¥ã™ã‚‹
1268 *   命令((b)行)が1つ余分にå…
1269¥ã£ã¦ã„る。
1270 *
1271 *   一方、mov.l @(imm, r),r0命令はオペランドがr0に固定されて
1272 *   いない。
1273 *   SH3版のようにmakeoffset.cでラベルBIT_BWを指定すれば、4バ
1274 *   イト単位でオフセットとマスクが生成されるので、mov.l命令が
1275 *   使え、レジスタ割付が楽になるが、enatex判定時のマスクデー
1276 *   タがand命令のイミディエート値に収まり切らなくなるため、
1277 *   ロード命令が1つ余分にå…
1278¥ã‚‹ã€‚
1279 *   どちらも一長一短があるが、いずれにしろ、runtskを再ロード
1280 *   するよりはマシと思われる。
1281 */
Note: See TracBrowser for help on using the repository browser.