source: asp3_gr_sakura/trunk/arch/rx630_gcc/prc_kernel_impl.h@ 318

Last change on this file since 318 was 318, checked in by coas-nagasima, 7 years ago

プロパティの文字コードにUTF-8を追加、キーワードを削除

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr; charset=UTF-8
File size: 20.2 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced 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) 2005,2006 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 * Copyright (C) 2008-2010 by Witz Corporation, JAPAN
11 * Copyright (C) 2013 by Mitsuhiro Matsuura
12 *
13 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
14 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
15 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
21 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
22 * の無保証規定を掲載すること.
23 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
25 * と.
26 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
27 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
28 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
29 * 報告すること.
30 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
31 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
32 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
33 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
34 * 免責すること.
35 *
36 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
37 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
38 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
39 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
40 * の責任を負わない.
41 *
42 * @(#) $Id$
43 */
44
45/*
46 * プロセッサ依存モジュール(RX630用)
47 *
48 * このインクルードファイルは,target_kernel_impl.h(または,そこからインク
49 * ルードされるファイル)のみからインクルードされる.他のファイルから
50 * 直接インクルードしてはならない.
51 */
52
53#ifndef TOPPERS_PRC_CONFIG_H
54#define TOPPERS_PRC_CONFIG_H
55
56/*
57 * プロセッサの特殊命令のインライン関数定義
58 */
59#include "prc_insn.h"
60#include "sil.h"
61
62#ifndef TOPPERS_MACRO_ONLY
63
64/*
65 * 非タスクコンテキスト用のスタック初期値
66 */
67
68#define TOPPERS_ISTKPT( istk, istksz ) (( STK_T * )(( char * )( istk ) + ( istksz )))
69
70/*
71 * タスクコンテキストブロックの定義
72 */
73typedef struct task_context_block {
74 void *sp; /* スタックポインタ */
75 FP pc; /* プログラムカウンタ */
76} TSKCTXB;
77
78
79/*
80 * 割込み発生回数を保存する変数
81 */
82extern uint16_t intnest;
83
84#endif /* TOPPERS_MACRO_ONLY */
85
86/*
87 * CPUロック状態での割込み優先度マスク
88 *
89 * TIPM_LOCKは,CPUロック状態での割込み優先度マスク,すなわち,カーネ
90 * ル管理外のものを除くすべての割込み要求をマスクする値に定義する.
91 *
92 * TMIN_INTPRI変更することで管理外割込みの有無を決定する.
93 * 例えばTMIN_INTPRIを-14に設定すると,レベル15の割込みがカーネル管理外と
94 * なる.TMIN_INTPRIを-15に設定すると,NMI以外にカーネル管理外の割込みを
95 * 設けないことになる(この場合には-15に設定することを推奨する).
96 */
97#ifndef TIPM_LOCK
98#define TIPM_LOCK TMIN_INTPRI
99#endif /* TIPM_LOCK */
100
101#ifndef TOPPERS_MACRO_ONLY
102
103/*
104 * TOPPERS標準割込み処理モデルの実現
105 */
106/*
107 * コンテキストの参照
108 *
109 * RXでは,割込みの戻り先がタスクかどうかを判断するために intnest
110 * を使用している.これを用いてコンテキストを判断する.
111 */
112Inline bool_t
113sense_context( void )
114{
115 /* ネストカウンタ0より大なら非タスクコンテキスト */
116 return ( intnest > 0U );
117}
118
119
120/*
121 * CPUロックフラグ実現のための変数
122 *
123 * これらの変数は,CPUロック状態の時のみ書き換えてよいものとする.
124 */
125#if TIPM_LOCK != -15
126extern bool_t lock_flag; /* CPUロックフラグの値を保持する変数 */
127extern uint32_t saved_ipl; /* 割込み優先度レベルを保存する変数 */
128#endif /* TIPM_LOCK != -15 */
129
130#endif /* TOPPERS_MACRO_ONLY */
131
132
133/*
134 * 割込み優先度マスクの外部表現と内部表現の変換
135 *
136 * RX630では,プロセッサステータスワードレジスタ(PSW)の下から
137 * 24~27ビット目の4ビットに割込み優先度レベル(IPL)が置かれている.
138 * カーネル管理外割込みを実装する場合にIPLを使用した制御を行う.
139 * カーネルは割込み優先度マスク(-1から連続した負の値)で管理されて
140 * いるためIPLとの変換が必要となる.
141 */
142#define IPL_TO_IPM( ipl ) (-(( PRI )(( ipl ) >> 24U ))) /* IPLをIPMに */
143#define IPM_TO_IPL( ipm ) ((( uint32_t )(-( ipm ))) << 24U ) /* IPMをIPLに */
144
145
146/*
147 * CPUロック状態での割込み優先度マスクのIPL
148 */
149#define IPL_LOCK ( IPM_TO_IPL( TIPM_LOCK ) )
150
151/*
152 * TIPM_ENAALL(割込み優先度マスク全解除)のIPL
153 */
154#define IPL_ENAALL ( IPM_TO_IPL( TIPM_ENAALL ) )
155
156
157#ifndef TOPPERS_MACRO_ONLY
158
159/*
160 * 割込み要因毎のレベル & 属性定義テーブル
161 * (テンプレートファイルによる出力)
162 */
163typedef struct cfg_int_info {
164 PRI intpri;
165 ATR intatr;
166} CFG_INT_INFO;
167
168extern const CFG_INT_INFO cfg_int_table[];
169
170
171/*
172 * 割込み番号の範囲の判定
173 *
174 * 割込み番号が有効な値か厳密にチェックするため,
175 * コンフィギュレータ出力テーブルを参照する.
176 */
177#define VALID_INTNO( intno ) \
178 ( cfg_int_table[( intno )].intpri > 0 )
179#define VALID_INTNO_DISINT( intno ) VALID_INTNO( intno )
180#define VALID_INTNO_CFGINT( intno ) VALID_INTNO( intno )
181
182/* cre_intで有効な割込み番号の指定 */
183#define VALID_INTNO_CREINT VALID_INTNO_CFGINT((intno))
184
185/* cre_isrで有効な割込み番号の指定 */
186#define VALID_INTNO_CREISR(intno) VALID_INTNO_CFGINT((intno))
187
188
189/*
190 * 割込み制御レジスタ関連の定義
191 */
192#define IRQ_POSEDGE ( 0x08U )
193#define IRQ_NEGEDGE ( 0x04U )
194#define IRQ_BOTHEDGE ( 0x0CU )
195#define IRQ_LOWLEVEL ( 0x00U )
196
197
198/*
199 * CPUロック状態への移行
200 *
201 * IPM(ハードウェアの割込み優先度マスク)を,saved_iipmに保存し,カー
202 * ネル管理外のものを除くすべての割込み要求をマスクする値(TIPM_LOCK)
203 * に設定する.また,lock_flagをTRUEにする.
204 *
205 * IPMが,最初からTIPM_LOCKと同じかそれより高い場合には,それを
206 * saved_iipmに保存するのみで,TIPM_LOCKには設定しない.これは,モデル
207 * 上の割込み優先度マスクが,TIPM_LOCKと同じかそれより高いレベルに設定
208 * されている状態にあたる.
209 *
210 * この関数は,CPUロック状態(lock_flagがTRUEの状態)で呼ばれることは
211 * ないものと想定している.
212 */
213Inline void
214lock_cpu( void )
215{
216#if TIPM_LOCK == -15
217 disint();
218#else /* TIPM_LOCK == -15 */
219 uint32_t ipl;
220
221 /*
222 * current_ipl()の返り値を直接saved_iplに保存せず,一時変数ipl
223 * を用いているのは,current_ipl()を呼んだ直後に割込みが発生し,
224 * 起動された割込み処理でsaved_iplが変更される可能性があるためで
225 * ある.
226 */
227 ipl = current_ipl();
228 if( IPL_LOCK > ipl ){
229 set_ipl( IPL_LOCK );
230 }
231
232 saved_ipl = ipl;
233 lock_flag = true;
234#endif /* TIPM_LOCK == -15 */
235}
236
237#define lock_cpu_dsp() lock_cpu()
238
239/*
240 * CPUロック状態の解除
241 *
242 * lock_flagをFALSEにし,IPM(ハードウェアの割込み優先度マスク)を,
243 * saved_iipmに保存した値に戻す.
244 *
245 * この関数は,CPUロック状態(lock_flagがtrueの状態)でのみ呼ばれるも
246 * のと想定している.
247 */
248Inline void
249unlock_cpu( void )
250{
251#if TIPM_LOCK == -15
252 enaint();
253#else /* TIPM_LOCK == -15 */
254 lock_flag = false;
255 set_ipl( saved_ipl );
256#endif /* TIPM_LOCK == -15 */
257}
258
259#define unlock_cpu_dsp() unlock_cpu()
260
261/*
262 * CPUロック状態の参照
263 */
264Inline bool_t
265sense_lock( void )
266{
267#if TIPM_LOCK == -15
268 return (( bool_t )(( current_psw() & PSW_I_MASK) == 0 ));
269#else /* TIPM_LOCK == -15 */
270 return lock_flag;
271#endif /* TIPM_LOCK == -15 */
272}
273
274
275/*
276 * 割込み属性の設定のチェック
277 */
278Inline bool_t
279check_intno_cfg(INTNO intno)
280{
281 return(cfg_int_table[intno].intpri != 0U);
282}
283
284/*
285 * (モデル上の)割込み優先度マスクの設定
286 *
287 * CPUロックフラグがクリアされている時は,ハードウェアの割込み優先度マ
288 * スクを設定する.CPUロックフラグがセットされている時は,saved_iipm
289 * を設定し,さらに,ハードウェアの割込み優先度マスクを,設定しようと
290 * した(モデル上の)割込み優先度マスクとTIPM_LOCKの高い方に設定する.
291 */
292Inline void
293t_set_ipm( PRI intpri )
294{
295 uint32_t ipl = IPM_TO_IPL( intpri );
296#if TIPM_LOCK == -15
297 set_ipl(ipl);
298#else /* TIPM_LOCK == -15 */
299 if( !lock_flag ){
300 set_ipl(ipl);
301 }
302 else {
303 saved_ipl = ipl;
304 set_ipl(ipl > IPL_LOCK ? ipl : IPL_LOCK);
305 }
306#endif /* TIPM_LOCK == -15 */
307}
308
309
310
311/*
312 * (モデル上の)割込み優先度マスクの参照
313 *
314 * CPUロックフラグがクリアされている時はハードウェアの割込み優先度マ
315 * スクを,セットされている時はsaved_iipmを参照する.
316 */
317Inline PRI
318t_get_ipm( void )
319{
320 uint32_t ipl;
321#if TIPM_LOCK == -15
322 ipl = current_ipl();
323#else /* TIPM_LOCK == -15 */
324 if (!lock_flag) {
325 ipl = current_ipl();
326 }
327 else {
328 ipl = saved_ipl;
329 }
330#endif /* TIPM_LOCK == -15 */
331 return IPL_TO_IPM( ipl );
332}
333
334
335
336/*
337 * 割込み要求禁止フラグのセット
338 *
339 * 割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
340 * フラグをセットしようとした場合には,FALSEを返す.
341 */
342Inline bool_t
343disable_int( INTNO intno )
344{
345 /*
346 * レベル定義が0である場合はCFG_INTされていない
347 */
348 if( cfg_int_table[intno].intpri == 0 ){
349 return ( false );
350 }
351
352 *ier_reg_addr[intno].addr &= ( ~ier_reg_addr[intno].offset );
353
354 return ( true );
355}
356
357
358/*
359 * 割込み要求禁止フラグのクリア
360 *
361 * 割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
362 * フラグをクリアしようとした場合には,FALSEを返す.
363 */
364Inline bool_t
365enable_int( INTNO intno )
366{
367 /*
368 * レベル定義が0である場合はCFG_INTされていない
369 */
370 if( cfg_int_table[intno].intpri == 0 ){
371 return ( false );
372 }
373
374 *ier_reg_addr[intno].addr |= ier_reg_addr[intno].offset;
375
376 return ( true );
377}
378
379
380/*
381 * 割込み要求がクリアできる状態か?
382 */
383Inline bool_t
384check_intno_clear(INTNO intno)
385{
386 return(true);
387}
388
389/*
390 * 割込み要求のクリア
391 */
392Inline void
393clear_int( INTNO intno )
394{
395 *IR_REG(intno) = 0U;
396}
397
398
399/*
400 * 割込みが要求できる状態か?
401 */
402Inline bool_t
403check_intno_raise(INTNO intno)
404{
405 return(true);
406}
407
408/*
409 * 割込みの要求
410 * 注意:チップでサポートされていない操作
411 */
412Inline void
413raise_int( INTNO intno )
414{
415 *IR_REG(intno) = 1U;
416}
417
418/*
419 * 割込み要求のチェック
420 */
421Inline bool_t
422probe_int( INTNO intno )
423{
424 /*
425 * 割込み要求レジスタは0 or 1でしかないため,
426 * そのままの値を返す.
427 */
428 return ( *IR_REG(intno) );
429}
430
431/*
432 * 割込み要求ラインの属性の設定
433 */
434extern void config_int( INTNO intno, ATR intatr, PRI intpri );
435
436/*
437 * 割込みを受け付けるための遅延処理
438 */
439Inline void
440delay_for_interrupt(void)
441{
442}
443
444/*
445 * 最高優先順位タスクへのディスパッチ(prc_support.a30)
446 *
447 * dispatchは,タスクコンテキストから呼び出されたサービスコール処理か
448 * ら呼び出すべきもので,タスクコンテキスト・CPUロック状態・ディスパッ
449 * チ許可状態・(モデル上の)割込み優先度マスク全解除状態で呼び出さな
450 * ければならない.
451 */
452extern void dispatch( void );
453
454/*
455 * 非タスクコンテキストからのディスパッチ要求
456 */
457#define request_dispatch()
458
459/*
460 * ディスパッチャの動作開始(prc_support.a30)
461 *
462 * start_dispatchは,カーネル起動時に呼び出すべきもので,すべての割込
463 * みを禁止した状態(全割込みロック状態と同等の状態)で呼び出さなければ
464 * ならない.
465 */
466extern void start_dispatch( void ) NoReturn;
467
468/*
469 * 現在のコンテキストを捨ててディスパッチ(prc_support.a30)
470 *
471 * exit_and_dispatchは,ext_tskから呼び出すべきもので,タスクコンテキ
472 * スト・CPUロック状態・ディスパッチ許可状態・(モデル上の)割込み優先
473 * 度マスク全解除状態で呼び出さなければならない.
474 */
475#define _kernel_exit_and_dispatch(); \
476 _exit_and_dispatch(); \
477 ercd = E_SYS;
478
479extern void _exit_and_dispatch( void ) NoReturn;
480
481/*
482 * カーネルの終了処理の呼出し(prc_support.a30)
483 *
484 * call_exit_kernelは,カーネルの終了時に呼び出すべきもので,非タスク
485 * コンテキストに切り換えて,カーネルの終了処理(exit_kernel)を呼び出
486 * す.
487 */
488extern void call_exit_kernel( void ) NoReturn;
489
490/*
491 * タスクコンテキストの初期化
492 *
493 * タスクが休止状態から実行できる状態に移行する時に呼ばれる.この時点
494 * でスタック領域を使ってはならない.
495 *
496 * activate_contextを,インライン関数ではなくマクロ定義としているのは,
497 * この時点ではTCBが定義されていないためである.
498 */
499extern void start_r( void );
500
501#define activate_context( p_tcb ) \
502{ \
503 { \
504 \
505 /* スタックポインタ初期値の設定 */ \
506 ( p_tcb )->tskctxb.sp = ( void * )((( uint32_t ) ( p_tcb )->p_tinib->stk ) + \
507 ( p_tcb )->p_tinib->stksz ); \
508 /* 起動番地の設定 */ \
509 ( p_tcb )->tskctxb.pc = ( FP ) start_r; \
510 } \
511}
512
513
514/*
515 * calltexは使用しない
516 */
517#define OMIT_CALLTEX
518
519
520/*
521 * 割込みハンドラの設定
522 *
523 * RX630はROMに割込みベクタを配置するため,本関数は空関数で実装する.
524 */
525Inline void
526define_inh( INHNO inhno, FP inthdr )
527{
528}
529
530/*
531 * CPU例外ハンドラの設定
532 *
533 * RX630はROMに例外ベクタを配置するため,本関数は空関数で実装する.
534 */
535Inline void
536define_exc( EXCNO excno, FP exchdr )
537{
538}
539
540/*
541 * 割込み/例外ハンドラの入口処理の生成マクロ
542 *
543 * テンプレートファイルにより生成するため空マクロとする.
544 */
545#define HDR_ENTRY(hdr, intexc_num , tobejmp)
546
547/*
548 * 割込みハンドラの入口処理の生成マクロ
549 */
550#define _INT_ENTRY(inhno, inthdr) _kernel_##inthdr##_##inhno##_entry
551#define INT_ENTRY(inhno, inthdr) _INT_ENTRY(inhno , inthdr)
552
553#define _INTHDR_ENTRY(inhno, inhno_num ,inthdr) \
554 extern void _kernel_##inthdr##_##inhno##_entry(void);
555#define INTHDR_ENTRY(inhno, inhno_num ,inthdr) _INTHDR_ENTRY(inhno, inhno_num ,inthdr)
556
557
558/*
559 * CPU例外ハンドラの入口処理の生成マクロ
560 */
561#define _EXC_ENTRY(excno , exchdr) _kernel_##exchdr##_##excno##_entry
562#define EXC_ENTRY(excno , exchdr) _EXC_ENTRY(excno , exchdr)
563
564#define _EXCHDR_ENTRY(excno , excno_num , exchdr) \
565 extern void _kernel_##exchdr##_##excno##_entry(void);
566#define EXCHDR_ENTRY(excno , excno_num , exchdr) _EXCHDR_ENTRY(excno , excno_num , exchdr)
567
568
569/*
570 * CPU例外の発生した時のコンテキストの参照
571 *
572 * CPU例外の発生した時のコンテキストが,タスクコンテキストの時にFALSE,
573 * そうでない時にtrueを返す.
574 */
575Inline bool_t
576exc_sense_context( void *p_excinf )
577{
578 /*
579 * ネストカウンタが1より大なら非タスクコンテキスト
580 */
581 return( intnest > 1U );
582}
583
584#endif /* TOPPERS_MACRO_ONLY */
585
586/*
587 * CPU例外情報 p_excinf から PSW の値を取得するためのオフセット値
588 * EXCNO + ACC + FPSW + R1~R15 + PC
589 */
590#define EXC_GET_PSW_OFFSET (4+8+4+60+4)
591
592#ifndef TOPPERS_MACRO_ONLY
593
594/*
595 * CPU例外の発生した時のIPLの参照
596 */
597Inline uint32_t
598exc_get_ipl(void *p_excinf)
599{
600 return((*((uint32_t *)((uintptr_t)p_excinf+EXC_GET_PSW_OFFSET)))
601 & PSW_IPL_MASK);
602}
603
604Inline bool_t
605exc_sense_i(void *p_excinf)
606{
607 return((*(((uint32_t *)((uintptr_t)p_excinf+EXC_GET_PSW_OFFSET)))
608 & PSW_I_MASK) != 0u);
609}
610
611
612/*
613 * CPU例外の発生した時のコンテキストと割込みのマスク状態の参照
614 *
615 * CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコ
616 * ンテキストであり,全割込みロック状態でなく,CPUロック状態でなく,(モ
617 * デル上の)割込み優先度マスク全解除状態である時にtrue,そうでない時
618 * にFALSEを返す(CPU例外がカーネル管理外の割込み処理中で発生した場合
619 * にもFALSEを返す).
620 *
621 * カーネル実行中でない→ (TIPM_LOCK== -15) Iフラグ == 1
622 * (else) IPL < IPL_LOCK
623 * タスクコンテキストである→intnest == 0
624 * 全割込みロックでない→ Iフラグ == 1
625 * 割込み優先度マスクが全解除→IPL == 0
626 *
627 *
628 */
629Inline bool_t
630exc_sense_intmask(void *p_excinf)
631{
632 return((!exc_sense_context(p_excinf))
633 && exc_sense_i(p_excinf)
634 && (exc_get_ipl(p_excinf) == IPL_ENAALL));
635}
636
637/*
638 * CPU例外の発生した時のコンテキストと割込み/CPUロック状態の参照
639 *
640 * CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコ
641 * ンテキストであり,全割込みロック状態でなく,CPUロック状態でない時に
642 * true,そうでない時にfalseを返す(CPU例外がカーネル管理外の割込み処
643 * 理中で発生した場合にもfalseを返す).
644 *
645 * カーネル実行中でない→ (TIPM_LOCK== -15) Iフラグ == 1
646 * (else) IPL < TIPM_LOCK
647 * タスクコンテキストである→intnest < 1
648 * 全割込みロックでない→ Iフラグ == 1
649 * CPUロック状態でない→(TIPM_LOCK== -15) Iフラグ == 1
650 * (else) IPL < TIPM_LOCK
651 */
652Inline bool_t
653exc_sense_unlock(void *p_excinf)
654{
655#if TIPM_LOCK == -15
656 return((!exc_sense_context(p_excinf))
657 && exc_sense_i(p_excinf));
658#else
659 return((!exc_sense_context(p_excinf))
660 && exc_sense_i(p_excinf)
661 && exc_get_ipl(p_excinf) < IPL_LOCK);
662#endif
663}
664
665
666/*
667 * プロセッサ依存の初期化
668 */
669extern void prc_initialize( void );
670
671/*
672 * プロセッサ依存の終了時処理
673 */
674extern void prc_terminate( void );
675
676
677#ifndef OMIT_DEFAULT_INT_HANDLER
678/*
679 * 未登録の割込みが発生した場合に呼び出される
680 */
681void default_int_handler( void );
682#endif /* OMIT_DEFAULT_INT_HANDLER */
683
684#ifndef OMIT_DEFAULT_EXC_HANDLER
685/*
686 * 未登録の例外が発生した場合に呼び出される
687 */
688void default_exc_handler( void );
689#endif /* OMIT_DEFAULT_EXC_HANDLER */
690
691
692#endif /* TOPPERS_MACRO_ONLY */
693
694#endif /* TOPPERS_PRC_CONFIG_H */
695
Note: See TracBrowser for help on using the repository browser.