OSDN Git Service

動作検証済み。DSPの負荷率を%で表示できるようになった。出力はsyslog()
[trx-305dsp/dsp.git] / trx305 / kernel / config / blackfin / cpu_support.S
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  *
9  *  TOPPERS/JSP for Blackfin
10  *
11  *  Copyright (C) 2004,2006,2006 by Takemasa Nakamura
12  *  Copyright (C) 2004 by Ujinosuke
13  *
14  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
15  *  によって公表されている GNU General Public License の Version 2 に記
16  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
17  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
18  *  利用と呼ぶ)することを無償で許諾する.
19  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
20  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
21  *      スコード中に含まれていること.
22  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
23  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
24  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
25  *      の無保証規定を掲載すること.
26  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
28  *      と.
29  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
30  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
31  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
32  *        報告すること.
33  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
34  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
35  *
36  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
37  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
38  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
39  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
40  *
41  *
42  */
43
44
45 /*
46  *  プロセッサ依存モジュール アセンブリ言語部(BLACKfin用)
47  *  Copyright (C) 2004,2006,2006 by Takemasa Nakamura
48  */
49
50             // 32bit レジスタに即値をロードするマクロ
51 #ifdef __GNUC__
52 #define LOADLABEL( reg, value32 ) reg##.h = value32; reg##.l = value32;
53 #define LOADVALUE( reg, value32 ) reg##.h = ( value32 >> 16 ) &0xFFFF; reg##.l = value32 & 0xFFFF;
54 #elif defined(__ECC__)
55 #define LOADVALUE( reg, value32 ) reg##.h = hi(value32); reg##.l = lo(value32);
56 #define LOADLABEL LOADVALUE
57 #else
58 #error "Compiler is not supported"
59 #endif
60
61
62
63 #define _MACRO_ONLY
64 #include "jsp_kernel.h"
65 #include "offset.h"
66
67 /*
68  *  タスクディスパッチャ
69  *
70  *  dispatch は,割込み禁止状態で呼び出さなければならな
71  *  い.exit_and_dispatch も,割込み禁止状態で呼び出す。
72  *  p0 : &runtsk
73  *  p1 : &schedtsk
74  *  p2 : runtsk
75  *  p3 : schedtsk
76  *  p4 : &reqflg
77  */
78 #ifdef __GNUC__
79 .section .text;
80 #elif defined(__ECC__)
81 .section program;
82 #else
83 #error "Compiler is not supported"
84 #endif
85
86 .global _dispatch;
87 .global _idle_cycle;
88 .global _exit_and_dispatch;
89 .extern ldf_stack_end;
90 .extern _reqflg;
91 .extern _call_texrtn;
92 .extern _runtsk, _schedtsk;
93 #ifdef __GNUC__
94 .type _dispatch, STT_FUNC;
95 #elif defined(__ECC__)
96 #else
97 #error "Compiler is not supported"
98 #endif
99 _dispatch:
100     [--sp] = (r7:4, p5:3);
101     [--sp] = rets;
102     [--sp] = fp;
103     LOADLABEL( p0,  _runtsk )
104     LOADLABEL( p1,  _schedtsk)
105     p2 = [p0];                  // p2 を runtsk に
106     [p2+TCB_sp] = sp;           // タスクスタックを保存
107     LOADLABEL( r1, dispatch_r ) // 実行再開番地を保存
108     [p2+TCB_pc] = r1;
109             // スケジュールされたタスクを取り出す
110 dispatcher:
111     r0 = [p1];
112     [p0] = r0;                  // runtsk = schedtsk
113     cc = r0;
114     if !cc jump dispatcher_1;   // runtskが無ければ割り込み待ちに。
115     p3 = r0;                    // p3はschedtsk
116     sp = [p3+TCB_sp];           // タスクスタック復帰
117     p5 = [p3+TCB_pc];           // 実行再開番地復帰
118     jump (p5);                  // 実行再開番地へ飛ぶ
119
120             // ready タスクがない場合の割込み待ち
121 dispatcher_1:
122     LOADLABEL( r0, ldf_stack_end)   // イベントスタックポインタを設定
123     sp = r0;
124     LOADLABEL( p4, _reqflg )
125 wait_for_intr:
126     csync;
127     raise 14;                   // 割り込み待ち状態に移行
128     csync;
129     /*
130      *  割り込み待ちはIVG14の割り込み状態で行う。ここでIVG14に遷移するのは
131      *  どのスタックを使うかという問題の解決と,割込みハンドラ内で
132      *  のタスクディスパッチの防止という2つの意味がある.
133      *
134      *  割込みを待つ間は,runtsk を NULL(=0)に設定しなければなら
135      *  ない.このように設定しないと,割込みハンドラから iget_tid
136      *  を呼び出した際の動作が仕様に合致しなくなる.
137      *
138      *  割り込み待ち状態はidleになるため、実際には割り込みではなくwakeup
139      *  イベントが捕捉され、それに伴う割り込みを処理することになる。
140      *  したがって割り込み待ちをおこなうためには、対応するSIC_IWRのビットを
141     *  1にしておかなければならない。
142      *  これはアプリケーションプログラマの責任で行う。
143      */
144     r0 = [p4];                  // reqflag取得
145     cc = r0;
146     if !cc jump wait_for_intr;  // reqflgが0なら割り込み待ち
147     r0 = 0;
148     [p4] = r0;                  // reqflgをクリア
149     jump dispatcher;
150
151
152             // タスクの再開番地。タスク例外の処理をおこない、
153             // dispatch()から戻る
154             // このアドレスへは必ず dispatcherから飛んでくる。
155             // したがって、p3は必ずschedtskの内容になっている。
156 dispatch_r:
157     fp = [sp++];
158     r2 = [p3+TCB_texptn];       // schedtsk->texptn
159     cc = r2 == 0;               // texptrnが0ならcc => 1
160 //  r0 = [p3+TCB_enatex];
161 //  LOADVALUE( r1, TCB_enatex_mask )
162     r0 = b[p3+TCB_enatex](z);
163     r1 = TCB_enatex_mask;
164     r0 = r0 & r1;               // enatexが0なら、az => 1
165     cc |= az;                   // cc = ( !enatex || ! texptn ) = !( enatex && texptn )
166     if cc jump dispatch_r_1(bp);    // if ( !enatex || !texptn ) 即リターン
167     sp += -12;                  // ダミー引数領域確保
168     call _call_texrtn;
169     sp += 12;                   // ダミー引数領域開放
170 dispatch_r_1:
171     rets = [sp++];
172     (r7:4, p5:3) = [sp++];
173     rts;
174 _dispatch.end:
175
176 #ifdef __GNUC__
177 .size   _dispatch, .-_dispatch
178 #elif defined(__ECC__)
179 #else
180 #error "Compiler is not supported"
181 #endif
182
183
184 /*
185  *  TOPPERS/JSP開始処理:
186  *   start.asm は kernel_startをCPUロック状態、タスク優先順位で呼ぶ。
187  *   kernel_startはそのままexit_and_dispatchを呼ぶ。
188  *   _exit_and_dispatchは、それまでのスタック状態などを単に廃棄し、
189  *   スケジュールされたタスクを開始する。
190 */
191 _exit_and_dispatch:
192         // dispatcher以降で使うポインタを設定
193     LOADLABEL( p0,  _runtsk )
194     LOADLABEL( p1,  _schedtsk)
195     jump dispatcher;
196 _exit_and_dispatch.end:
197
198 /*
199  *  タスク起動時処理
200  *  _activate_rへはかならずdispatcherから飛んでくる。そのため、CPUロックを
201  * はずさなければならない。
202  */
203
204     .global _activate_r;
205 _activate_r:
206     fp = 0;
207     r1 = 0xffff(z);
208     cli r0;         // 現在のマスクを取り出す。
209                         // 管理外割り込みを使わないときにも、割り込み禁止のためcliが必要
210 #ifdef UNMANAGED_INT
211     r2 = UNMANAGED_INT(z);
212     r0 = r0 & r2;               // 管理外割り込みのみ取り出す
213     r2 = ~r2;                   // 逆マスク
214     r1 = r1 & r2;               //
215     r1 = r1 | r0;               // 管理外割り込みを考慮したマスク
216 #endif
217     sti r1;             // CPU アンロック
218     p0 = [sp++];        // タスクエントリーを取り出す
219     r0 = [sp++];        // ext_tskの番地を取り出す
220     rets = r0;          // ext_tskをダミーの戻り番地にする
221     r0 = [sp++];        // ext_infを取り出す : r0 は引数1
222     sp += -12;
223     jump (p0);          // タスクの開始
224 _activate_r.end:
225
226
227 /*
228 *   割込み処理のエントリ
229 *
230 *   interrupt_handlerへはivgXXEntryからジャンプしてくる。p0レジスタには
231 *   割り込みレベル番号が格納されている。
232 *   割り込みとのネスト関係を調べ、ネストしていないならイベントスタックをセットする。
233 *       p2 : reqflgのアドレス
234 *       r6 : タスクスタック
235 *       r7 : ASTATの退避情報
236 *
237 */
238
239 #include "saverestore.h"
240
241 .global interrupt_dispatcher;
242 .global task_context;
243 .extern _device_dispatcher, _enadsp;
244 .extern _event_fp;
245
246 #ifdef __GNUC__
247 .type interrupt_dispatcher, STT_FUNC;
248 #elif defined(__ECC__)
249 #else
250 #error "Compiler is not supported"
251 #endif
252 interrupt_dispatcher:
253                 // save all task context register
254     save_regs;                  // ユーザーレジスタの退避
255     r0 = 0;
256     l0 = r0;
257     l1 = r0;
258     l2 = r0;
259     l3 = r0;
260     lc0 = r0;                   // 性能低下抑制のためにLCxをクリア
261     lc1 = r0;
262     LOADVALUE( p1, __IPEND )            // IPENDレジスタのアドレス
263     r0 = [p1];                  // IPENDの値を取得
264     r1 = 0x7fef;                //
265     r0 = r0 & r1;               // IVG15とGID以外を調べる
266     r0.L = ones r0;             // 処理中のイベントの数を数える
267     r0 += -1;                   // イベントの数-1。ネストしていなければ0になる。
268     cc = az;                    // ネストしてなければ真
269     if !cc jump call_interrupt; // もしネストしていればハンドラを呼ぶ
270                                 // ネストしていない割り込みなら、スタックを切り替える
271     r6 = sp;                    // タスクスタックポインタを退避
272     LOADLABEL( r0, ldf_stack_end)   // イベントスタックポインタを設定
273     sp = r0;
274
275 call_interrupt:
276     cli r1;                     // IMASKの古い値を第二パラメータに
277     [--sp] = reti;              // ここで割り込み可能になる
278     r7 = astat;                 // ccにはネスト情報が入っている。それを退避
279     r0 = p0;                    // 割り込み順位を第一パラメータに
280     LOADLABEL( p0, _device_dispatcher)
281     sp += -12;                  // ダミー引数確保 (A)
282     call    (p0);               // C言語で書かれたデバイスディスパッチャを呼ぶ
283     sp += 12;                   // ダミー引数開放 (A)
284     astat = r7;                 // ccを復帰
285     reti = [sp++];              // ここで再び割り込み禁止
286     if !cc jump get_back;       // もしネストしているならば、このまま帰る
287
288                                 // ここでは割り込みはネストしていない
289     sp = r6;                    // スタックをタスクスタックに設定
290
291     LOADLABEL( p2, _reqflg)         // reqflgのアドレス
292     r0 = [p2];                  // reqflgの値を取得
293     cc = r0;                    // ディスパッチかタスク例外の要求は出ているか
294     if !cc jump get_back(bp);   // 出ていないならば割り込まれたタスクに戻る
295
296                                 // コンテキスト切り替え作業開始
297     r0 = 0;                     //
298     [p2] = r0;                  // reqflgをクリアする.
299     r0 = reti;                  // タスクの戻り番地を取り出す
300     r1 = 1;
301     r0 = r1 | r0;               // セルフ・ネストであると偽装する
302     [--sp] = r0;                // 戻り番地をスタックにつむ
303     LOADLABEL( p0, task_context)
304
305     cli r0;                     // 現在のCPUロック状態を取得
306     [--sp] = r0;                // ロック状態を退避
307
308     r1 = 0xC01F(z);             // タスクコンテキストははCPUロック状態で実行する
309 #ifdef UNMANAGED_INT
310     r2 = UNMANAGED_INT(z);
311     r0 = r0 & r2;               // 管理外割り込みのマスク状態を抽出
312     r1 = r0 | r1;               // タスクコンテキストはCPUロック状態で実行する
313 #endif
314     sti r1;                     // CPUロック (B)
315
316     reti = p0;                  // ラベル"task_context"を割り込みからの戻り番地にする
317     rti;                        // 割り込みから戻る。コンテキストはタスクになる
318     csync;
319 task_context:                   // ここはタスクコンテキストで、CPUロック状態である
320     LOADLABEL( p0, _enadsp)
321     LOADLABEL( p1, _runtsk)
322
323
324     r2 = [p0];                  // load enadsp
325     cc = r2;                    // ディスパッチ可能か?
326     if !cc jump go_tex;         // もしディスパッチ禁止なら例外チェックに
327
328     LOADLABEL( p0, _schedtsk)       // ディスパッチ可能の場合
329     r1 = [p1];                  // runtsk
330     r0 = [p0];                  // schedtsk
331     cc = r0 == r1;              // schedtsk == runtsk か?
332     if cc jump go_tex(bp);      // もし schedtsk == runtsk ならば、タスク例外に行く
333                                 // そうでなければディスパッチする
334     sp += -12;                  // ダミー引数領域確保 (C)
335     call _dispatch;             // レッツゴー
336     sp += 12;                   // ダミー引数領域開放 (C)
337     jump return_as_task;        // タスクに戻る
338
339 go_tex:
340     p1 = [p1];                  // runtsk
341     r0 = [p1 + TCB_texptn];     // runtsk->texptrnを取得 ( UINT )
342     cc = r0 == 0;               // texptnが0なら1
343 //  r0 = [p1 + TCB_enatex];     // runtsk->enatexを取得
344 //  LOADVALUE( r1, TCB_enatex_mask)
345     r0 = b[p1 + TCB_enatex](z);     // runtsk->enatexを取得
346     r1 = TCB_enatex_mask;
347     r1 = r0 & r1;               // タスク例外が許可されていなければ1
348     cc |= az;                   // 例外が許可されていないか、texptnが0ならば即帰る
349     if cc jump return_as_task(bp);  // 許可されていなければタスクに戻る
350     sp += -12;                  // ダミー引数領域確保 (D)
351     call _call_texrtn;          // 条件がそろったのでタスク例外処理を行う。
352     sp += 12;                   // ダミー引数領域開放 (D)
353
354 return_as_task:                 // タスクコンテキスト状態での戻り
355     r0 = [sp++];                // 退避していたロック状態
356     reti = [sp++];              // 戻り番地を復帰。以後rtiまで割込み禁止
357     cli r1;               // 現在のロック状態を取り出す
358                                 // 管理外割り込みを使わない場合もこのcliは保護のため必要
359 #ifdef UNMANAGED_INT
360     r2 = UNMANAGED_INT(z);
361     r1 = r1 & r2;               // 実行中のマスクから管理外割り込みの状態を抽出
362     r2 = ~ r2;                  // UNMANAGED_INTの逆マスク
363     r0 = r0 & r2;               // 退避中のロック状態から管理外割り込みマスクをクリア
364     r0 = r0 | r1;               // 退避していたロック状態をアップデート
365 #endif
366     sti r0;                     // CPUロックを解除(B)(F)
367
368
369 get_back:                       // 非タスクコンテキスト状態での戻り
370     restore_regs;               // 退避したレジスタを全て戻す
371     p0=[sp++];
372     rti;                        // タスクに戻る
373
374
375 #ifdef __GNUC__
376 .size   interrupt_dispatcher, .-interrupt_dispatcher
377 #elif defined(__ECC__)
378 interrupt_dispatcher.end:
379 #else
380 #error "Compiler is not supported"
381 #endif
382
383
384 .global expEntry
385 .global expEntry;
386 .global nmiEntry;
387 .global ivHWEntry;
388 .global ivTMREntry;
389 .global ivg7Entry;
390 .global ivg8Entry;
391 .global ivg9Entry;
392 .global ivg10Entry;
393 .global ivg11Entry;
394 .global ivg12Entry;
395 .global ivg13Entry;
396 .global ivg14Entry;
397 #ifdef __GNUC__
398 .section .text;
399 .type expEntry, STT_FUNC;
400 .type nmiEntry, STT_FUNC;
401 .type ivTMREntry, STT_FUNC;
402 .type ivHWEntry, STT_FUNC;
403 .type ivg7Entry, STT_FUNC;
404 .type ivg8Entry, STT_FUNC;
405 .type ivg9Entry, STT_FUNC;
406 .type ivg10Entry, STT_FUNC;
407 .type ivg11Entry, STT_FUNC;
408 .type ivg12Entry, STT_FUNC;
409 .type ivg13Entry, STT_FUNC;
410 .type ivg14Entry, STT_FUNC;
411 #elif defined(__ECC__)
412 .section program;
413 #else
414 #error "Compiler is not supported"
415 #endif
416
417
418 /*
419 *   例外処理のエントリ
420 *
421 *   割り込みとのネスト関係を調べ、ネストしていないならイベントスタックをセットする。
422 *       p0 : ユーザー定義の例外ハンドラのアドレス
423 *       p1 : IPENDのアドレス
424 *       p2 : reqflgのアドレス
425 *       r6 : タスクスタック
426 *       r7 : ASTATの退避情報
427 *
428 */
429 expEntry:
430     [--sp] = p0;
431     save_regs;                  // ユーザーレジスタの退避
432
433     LOADLABEL( p0, _exc_vector)     // ユーザー定義例外ハンドラの格納アドレス
434     LOADVALUE( p1, __IPEND )            // IPENDレジスタのアドレス
435
436     l0 = r0;
437     l1 = r0;
438     l2 = r0;
439     l3 = r0;
440     lc0 = r0;                   // 性能低下抑制のためにLCxをクリア
441     lc1 = r0;
442
443     p0 = [p0];                  // p0 = exc_vector
444     r0 = [p1];                  // IPENDの値を取得
445     r1 = 0x7fef;                //
446     r0 = r0 & r1;               // IVG15とGID以外を調べる. r0.Hは必ず0
447     r0.L = ones r0;             // 処理中のイベントの数を数える
448     r0 += -1;                   // イベントの数-1。ネストしていなければ0になる。
449     cc = r0 == 0;               // ネストしてなければ真
450     if !cc jump call_exception; // もしネストしていればハンドラを呼ぶ
451                                 // ネストしていないイベントなら、スタックを切り替える
452     r6 = sp;                    // タスクスタックポインタを退避
453     LOADLABEL( r0, ldf_stack_end)   // イベントスタックポインタを設定
454     sp = r0;
455
456 call_exception:
457     r7 = astat;                 // ccにはネスト情報が入っている。それを退避
458     r0 = p1;                    // 第一引数はIPENDのアドレス
459     sp += -12;                  // ダミー引数領域確保 (E)
460     call    (p0);               // C言語で書かれた例外ハンドラを呼ぶ
461     sp += 12;                   // ダミー引数領域開放 (E)
462     astat = r7;                 // ccを復帰
463     if !cc jump get_back_x;     // もしネストしているならば、このまま帰る
464
465                                 // ここではイベントはネストしていない
466     sp = r6;                    // スタックをタスクスタックに設定
467
468     LOADLABEL( p2, _reqflg )
469     r0 = [p2];                  // reqflgの値を取得
470     cc = r0;                    // ディスパッチかタスク例外の要求は出ているか
471     if !cc jump get_back_x;     // 出ていないならば割り込まれたタスクに戻る
472
473                                 // コンテキスト切り替え作業開始
474     r0 = 0;                     //
475     [p2] = r0;                  // reqflgをクリアする.
476     r0 = retx;                  // タスクの戻り番地を取り出す
477     r1 = 1;
478     r0 = r1 | r0;               // セルフ・ネストであると偽装する
479     [--sp] = r0;                // 戻り番地をスタックにつむ
480     LOADLABEL( p0, task_context)
481
482     cli r0;                     // 現在のCPUロック状態を取得
483     [--sp] = r0;                // ロック状態を退避
484     r1 = 0xC01F(z);             // タスクコンテキストははCPUロック状態で実行する
485
486 #ifdef UNMANAGED_INT
487     r2 = UNMANAGED_INT(z);
488     r0 = r0 & r2;               // 管理外割り込みのマスク状態を抽出
489     r1 = r0 | r1;               // タスクコンテキストはCPUロック状態で実行する
490 #endif
491     sti r1;                     // CPUロック (F)
492
493     retx = p0;                  // ラベル"taskiv_context"を例外からの戻り番地にする
494     rtx;                        // 例外から戻る。コンテキストはタスクになる
495
496 get_back_x:
497     restore_regs;               // 退避したレジスタを全て戻す
498     p0=[sp++];
499     rtx;
500
501
502 #ifdef __GNUC__
503 .size   expEntry, .-expEntry
504 #elif defined(__ECC__)
505 expEntry.end:
506 #else
507 #error "Compiler is not supported"
508 #endif
509
510
511
512 // イベントハンドラのエントリーコード群。
513 // EVTのエントリには対応する以下のコードのラベルが格納される。
514 // それぞれのコードはイベント中にをp0に格納した後、
515 // interrupt_dispatcherにジャンプする
516 // evtvectorはユーザーハンドラへのポインタの配列
517
518
519
520
521 ivHWEntry:
522     [--sp] = p0;
523     p0 = 5;
524     jump.x interrupt_dispatcher;
525 #ifdef __GNUC__
526 .size   ivHWEntry, .-ivHWEntry
527 #elif defined(__ECC__)
528 ivHWEntry.end:
529 #else
530 #error "Compiler is not supported"
531 #endif
532
533
534 ivTMREntry:
535     [--sp] = p0;
536     p0 = 6;
537     jump.x interrupt_dispatcher;
538 #ifdef __GNUC__
539 .size   ivTMREntry, .-ivTMREntry
540 #elif defined(__ECC__)
541 ivTMREntry.end:
542 #else
543 #error "Compiler is not supported"
544 #endif
545
546
547 ivg7Entry:
548     [--sp] = p0;
549     p0 = 7;
550     jump.x interrupt_dispatcher;
551 #ifdef __GNUC__
552 .size   ivg7Entry, .-ivg7Entry
553 #elif defined(__ECC__)
554 ivg7Entry.end:
555 #else
556 #error "Compiler is not supported"
557 #endif
558
559 ivg8Entry:
560     [--sp] = p0;
561     p0 = 8;
562     jump.x interrupt_dispatcher;
563 #ifdef __GNUC__
564 .size   ivg8Entry, .-ivg8Entry
565 #elif defined(__ECC__)
566 ivg8Entry.end:
567 #else
568 #error "Compiler is not supported"
569 #endif
570
571 ivg9Entry:
572     [--sp] = p0;
573     p0 = 9;
574     jump.x interrupt_dispatcher;
575 #ifdef __GNUC__
576 .size   ivg9Entry, .-ivg8Entry
577 #elif defined(__ECC__)
578 ivg9Entry.end:
579 #else
580 #error "Compiler is not supported"
581 #endif
582
583 ivg10Entry:
584     [--sp] = p0;
585     p0 = 10;
586     jump.x interrupt_dispatcher;
587 #ifdef __GNUC__
588 .size   ivg10Entry, .-ivg10Entry
589 #elif defined(__ECC__)
590 ivg10Entry.end:
591 #else
592 #error "Compiler is not supported"
593 #endif
594
595 ivg11Entry:
596     [--sp] = p0;
597     p0 = 11;
598     jump.x interrupt_dispatcher;
599 #ifdef __GNUC__
600 .size   ivg11Entry, .-ivg11Entry
601 #elif defined(__ECC__)
602 ivg11Entry.end:
603 #else
604 #error "Compiler is not supported"
605 #endif
606
607 ivg12Entry:
608     [--sp] = p0;
609     p0 = 12;
610     jump.x interrupt_dispatcher;
611 #ifdef __GNUC__
612 .size   ivg12Entry, .-ivg12Entry
613 #elif defined(__ECC__)
614 ivg12Entry.end:
615 #else
616 #error "Compiler is not supported"
617 #endif
618
619 ivg13Entry:
620     [--sp] = p0;
621     p0 = 13;
622     jump.x interrupt_dispatcher;
623 #ifdef __GNUC__
624 .size   ivg13Entry, .-ivg13Entry
625 #elif defined(__ECC__)
626 ivg13Entry.end:
627 #else
628 #error "Compiler is not supported"
629 #endif
630
631 ivg14Entry:                 // dispatch()の割り込み待ち部
632                                 // USE_HW_ERRORは互換性の為だけに残してある。
633 #if !defined(USE_TIC_CORE) && !defined(USE_HW_ERROR) && !defined(QUICK_HW_ERROR)
634     LOADLABEL( p5, _idle_cycle );
635     r0 = cycles;                // idle命令前のクロックを取得
636     csync;                      // コアタイマーでティックを刻むときにはidle命令を使えない。
637     idle;                       // イベント待ち
638     csync;
639     r1 = cycles;                // idle命令後のクロックを取得
640     r1 = r1 - r0;               // idle命令滞在時間を算出
641     r0 = [p5];                  // 累積idle_cycle値を読み出す
642     r0 = r0 + r1;
643     [p5] = r0;                  // 累積idle_cycle値を保存
644 #endif
645     [--sp] = reti;              // 割込みネスト許可
646     r1 = 0xffff(z);             // CPU アンロック用パターン
647 #ifdef UNMANAGED_INT
648     cli r0;               // 現在のマスクを取り出す
649     r2 = UNMANAGED_INT(z);
650     r0 = r0 & r2;               // 管理外割り込みのみ取り出す
651     r2 = ~r2;                   // 逆マスク
652     r1 = r1 & r2;               //
653     r1 = r1 | r0;               // 管理外割り込みを考慮したマスク
654 #endif
655     sti r1;                     // CPU アンロック
656     r1 = 0xC01F(z);             // CPU ロック用パターン
657     cli r0;               // 現在のマスクを取り出す
658                                 // 管理外割り込みを使わない場合も、保護のため必要
659 #ifdef UNMANAGED_INT
660     r2 = UNMANAGED_INT(z);
661     r0 = r0 & r2;               // 管理外割り込みのみ取り出す
662     r1 = r1 | r0;               // 管理外割り込みを考慮したマスク
663 #endif
664     sti r1;
665     reti=[sp++];                // 割込みネスト禁止
666     rti;
667 #ifdef __GNUC__
668 .size   ivg14Entry, .-ivg14Entry
669 #elif defined(__ECC__)
670 ivg14Entry.end:
671 #else
672 #error "Compiler is not supported"
673 #endif
674
675
676 nmiEntry:
677     jump    nmiEntry;
678     rtn;
679 #ifdef __GNUC__
680 .size   nmiEntry, .-nmiEntry
681 #elif defined(__ECC__)
682 nmiEntry.end:
683 #else
684 #error "Compiler is not supported"
685 #endif
686
687
688
689
690 /*
691  *  微少時間待ち
692  *  内側のループは12サイクルで回る。
693  */
694     .global _sil_dly_nse;
695 _sil_dly_nse:
696     r1 = SIL_DLY_TIM1;
697     r2 = SIL_DLY_TIM2;
698     r0 = r0 - r1;           // dilay - SIL_DLY_TIM1
699     cc = an;            // 結果が0より大きければ
700     if !cc jump _sil_dly_nse_1; // ループ
701     rts;
702 _sil_dly_nse_1:
703     r0 = r0 - r2;
704     nop;
705     cc = an;            // 結果が0より大きければ
706     if !cc jump _sil_dly_nse_1; // ループ
707     rts;
708 _sil_dly_nse.end:
709