OSDN Git Service

Sメーター周りを修正
[trx-305dsp/dsp.git] / hirado / kernel / config / m68k / cpu_config.h
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  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
10  *  によって公表されている GNU General Public License の Version 2 に記
11  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
13  *  利用と呼ぶ)することを無償で許諾する.
14  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16  *      スコード中に含まれていること.
17  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20  *      の無保証規定を掲載すること.
21  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23  *      と.
24  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
26  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27  *        報告すること.
28  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30  * 
31  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
35  * 
36  *  @(#) $Id: cpu_config.h,v 1.1 2009/01/31 05:27:37 suikan Exp $
37  */
38
39 /*
40  *  プロセッサ依存モジュール(M68040用)
41  *
42  *  このインクルードファイルは,t_config.h のみからインクルードされる.
43  *  他のファイルから直接インクルードしてはならない.
44  */
45
46 #ifndef _CPU_CONFIG_H_
47 #define _CPU_CONFIG_H_
48
49 /*
50  *  カーネルの内部識別名のリネーム
51  */
52 #include <cpu_rename.h>
53
54 /*
55  *  プロセッサの特殊命令のインライン関数定義
56  */
57 #ifndef _MACRO_ONLY
58 #include <cpu_insn.h>
59 #endif /* _MACRO_ONLY */
60
61 /*
62  *  chg_ipm/get_ipm をサポートするかどうかの定義
63  */
64 #define SUPPORT_CHG_IPM
65
66 /*
67  *  TCB 中のフィールドのビット幅の定義
68  *
69  *  cpu_context.h に入れる方がエレガントだが,参照の依存性の関係で,
70  *  cpu_context.h には入れられない.
71  */
72 #define TBIT_TCB_TSTAT      8   /* tstat フィールドのビット幅 */
73 #define TBIT_TCB_PRIORITY   8   /* priority フィールドのビット幅 */
74
75 #ifndef _MACRO_ONLY
76 /*
77  *  タスクコンテキストブロックの定義
78  */
79 typedef struct task_context_block {
80     VP  msp;        /* スタックポインタ */
81     FP  pc;     /* プログラムカウンタ */
82 } CTXB;
83
84 /*
85  *  割込みマスク操作ライブラリ
86  *
87  *  割込みマスク(intmask)は,IPM(Interrupt Priority Mask)を8ビット
88  *  左にシフトしたものである.
89  */
90
91 /*
92  *  現在の割込みマスクの読出し
93  */
94 Inline UH
95 current_intmask()
96 {
97     return(current_sr() & 0x0700);
98 }
99
100 /*
101  *  割込みマスクの設定
102  */
103 Inline void
104 set_intmask(UH intmask)
105 {
106     set_sr((current_sr() & ~0x0700) | intmask);
107 }
108
109 /*
110  *  システム状態参照
111  */
112
113 Inline BOOL
114 sense_context()
115 {
116     return((current_sr() & 0x1000) == 0);
117 }
118
119 Inline BOOL
120 sense_lock()
121 {
122     return(current_intmask() == 0x0700);
123 }
124
125 #define t_sense_lock    sense_lock
126 #define i_sense_lock    sense_lock
127
128 /*
129  *  CPUロックとその解除(タスクコンテキスト用)
130  *
131  *  task_intmask は,chg_ipm をサポートするための変数.chg_ipm をサポー
132  *  トしない場合には,task_intmask が常に 0 になっていると考えればよい.
133  */
134
135 #ifdef SUPPORT_CHG_IPM
136 extern UH   task_intmask;   /* タスクコンテキストでの割込みマスク */
137 #endif /* SUPPORT_CHG_IPM */
138
139 Inline void
140 t_lock_cpu()
141 {
142     disint();
143 }
144
145 Inline void
146 t_unlock_cpu()
147 {
148 #ifdef SUPPORT_CHG_IPM
149     /*
150      *  t_unlock_cpu が呼び出されるのは CPUロック状態のみであるた
151      *  め,処理の途中で task_intmask が書き換わることはない.
152      */
153     set_intmask(task_intmask);
154 #else /* SUPPORT_CHG_IPM */
155     enaint();
156 #endif /* SUPPORT_CHG_IPM */
157 }
158
159 /*
160  *  CPUロックとその解除(非タスクコンテキスト用)
161  */
162
163 extern UH   int_intmask;    /* 非タスクコンテキストでの割込みマスク */
164
165 Inline void
166 i_lock_cpu()
167 {
168     UH  intmask;
169
170     /*
171      *  一時変数 intmask を使っているのは,current_intmask() を呼
172      *  んだ直後に割込みが発生し,起動された割込みハンドラ内で
173      *  int_intmask が変更される可能性があるためである.
174      */
175     intmask = current_intmask();
176     disint();
177     int_intmask = intmask;
178 }
179
180 Inline void
181 i_unlock_cpu()
182 {
183     set_intmask(int_intmask);
184 }
185
186 /*
187  *  タスクディスパッチャ
188  */
189
190 /*
191  *  最高優先順位タスクへのディスパッチ(cpu_support.S)
192  *
193  *  dispatch は,タスクコンテキストから呼び出されたサービスコール処理
194  *  内で,CPUロック状態で呼び出さなければならない.
195  */
196 extern void dispatch(void);
197
198 /*
199  *  現在のコンテキストを捨ててディスパッチ(cpu_support.S)
200  *
201  *  exit_and_dispatch は,CPUロック状態で呼び出さなければならない.
202  */
203 extern void exit_and_dispatch(void);
204
205 /*
206  *  割込みハンドラ/CPU例外ハンドラの設定
207  */
208
209 /*
210  *  例外ベクタテーブルの構造の定義
211  */
212 typedef struct exc_vector_entry {
213     FP  exchdr;         /* 例外ハンドラの起動番地 */
214 } EXCVE;
215
216 /*
217  *  割込みハンドラの設定
218  *
219  *  ベクトル番号 inhno の割込みハンドラの起動番地を inthdr に設定する.
220  */
221 Inline void
222 define_inh(INHNO inhno, FP inthdr)
223 {
224     EXCVE   *excvt;
225
226 #ifdef EXCVT_KERNEL
227     /*
228      *  EXCVT_KERNEL が定義されている時は,初期化処理の中で VBR を 
229      *  EXCVT_KERNEL に設定するので,EXCVT_KERNEL を使う.
230      */
231     excvt = (EXCVE *) EXCVT_KERNEL;
232 #else /* EXCVT_KERNEL */
233     excvt = (EXCVE *) current_vbr();
234 #endif /* EXCVT_KERNEL */
235     excvt[inhno].exchdr = inthdr;
236 }
237
238 /*
239  *  CPU例外ハンドラの設定
240  *
241  *  ベクトル番号 excno のCPU例外ハンドラの起動番地を exchdr に設定する.
242  */
243 Inline void
244 define_exc(EXCNO excno, FP exchdr)
245 {
246     define_inh(excno, exchdr);
247 }
248
249 /*
250  *  割込みハンドラ/CPU例外ハンドラの出入口処理
251  */
252
253 /*
254  *  割込みハンドラの出入口処理の生成マクロ
255  *
256  *  reqflg をチェックする前に割込みを禁止しないと,reqflg をチェック後
257  *  に起動された割込みハンドラ内でディスパッチが要求された場合に,ディ
258  *  スパッチされない.
259  */
260
261 #define INTHDR_ENTRY(inthdr)        \
262 extern void inthdr##_entry(void);   \
263 asm(".text              \n" \
264 #inthdr "_entry:            \n" \
265 "   movem.l %d0-%d1/%a0-%a1, -(%sp) \n" /* スクラッチレジスタを保存 */ \
266 "   jsr " #inthdr "         \n" /* 割込みハンドラを呼び出す */ \
267 "   movem.l (%sp)+, %d0-%d1/%a0-%a1 \n" /* スクラッチレジスタを復帰 */ \
268 "   btst.b #4, (%sp)        \n" /* 戻り先が割込みモードなら */ \
269 "   jbeq 1f             \n" /*           すぐにリターン */ \
270 "   or.w #0x0700, %sr       \n" /* 割込み禁止 */ \
271 "   tst.l _kernel_reqflg        \n" /* reqflg が TRUE であれば */ \
272 "   jbne _kernel_ret_int        \n" /*              ret_int へ */ \
273 "1: rte             \n")
274
275 #define INT_ENTRY(inthdr)   inthdr##_entry
276
277 /*
278  *  CPU例外ハンドラの出入口処理の生成マクロ
279  *
280  *  CPU例外ハンドラは,非タスクコンテキストで実行する.そのため,CPU例
281  *  外ハンドラを呼び出す前に割込みモードに移行し,リターンしてきた後に
282  *  元のモードに戻す.元のモードに戻すために,割込みモードに移行する前
283  *  の SR を割込みスタック上に保存する.CPU例外がタスクコンテキストで
284  *  発生し,reqflg が TRUE になった時に,ret_exc へ分岐する.
285  *  reqflg をチェックする前に割込みを禁止しないと,reqflg をチェック後
286  *  に起動された割込みハンドラ内でディスパッチが要求された場合に,ディ
287  *  スパッチされない.
288  */
289
290 #define EXCHDR_ENTRY(exchdr)        \
291 extern void exchdr##_entry(VP sp);  \
292 asm(".text              \n" \
293 #exchdr "_entry:            \n" \
294 "   movem.l %d0-%d1/%a0-%a1, -(%sp) \n" /* スクラッチレジスタを保存 */ \
295 "   lea.l 16(%sp), %a0      \n" /* 例外フレームの先頭を A0 に */ \
296 "   move.w %sr, %d0         \n" /* SR を D0 に */ \
297 "   and.w #~0x1000, %sr     \n" /* 割込みモード */ \
298 "   move.l %d0, -(%sp)      \n" /* 元の SR をスタックに保存 */ \
299 "   move.l %a0, -(%sp)      \n" /* A0 を引数として渡す */ \
300 "   jsr " #exchdr "         \n" /* CPU例外ハンドラを呼び出す */ \
301 "   addq.l #4, %sp          \n" \
302 "   move.l (%sp)+, %d0      \n" \
303 "   and.w #0x1000, %d0      \n" /* 元が割込みモードなら */ \
304 "   jbeq 1f             \n" /*       すぐにリターン */ \
305 "   or.w #0x1700, %sr       \n" /* マスタモード・割込み禁止 */ \
306 "   tst.l _kernel_reqflg        \n" /* reqflg が TRUE であれば */ \
307 "   jbne _kernel_ret_exc        \n" /*              ret_exc へ */ \
308 "1: movem.l (%sp)+, %d0-%d1/%a0-%a1 \n" /* スクラッチレジスタを復帰 */ \
309 "   rte             \n")
310
311 #define EXC_ENTRY(exchdr)   exchdr##_entry
312
313 /*
314  *  CPU例外の発生した時のシステム状態の参照
315  */
316
317 /*
318  *  CPU例外の発生した時のコンテキストの参照
319  */
320 Inline BOOL
321 exc_sense_context(VP p_excinf)
322 {
323     return((*((UH *) p_excinf) & 0x1000) == 0);
324 }
325
326 /*
327  *  CPU例外の発生した時のCPUロック状態の参照
328  */
329 Inline BOOL
330 exc_sense_lock(VP p_excinf)
331 {
332     return((*((UH *) p_excinf) & 0x0700) == 0x0700);
333 }
334
335 /*
336  *  プロセッサ依存の初期化
337  */
338 extern void cpu_initialize(void);
339
340 /*
341  *  プロセッサ依存の終了時処理
342  */
343 extern void cpu_terminate(void);
344
345 #endif /* _MACRO_ONLY */
346 #endif /* _CPU_CONFIG_H_ */