source: rubycfg_asp/trunk/asp_dcre/arch/rx630_ccrx/prc_config.h@ 315

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

SVNプロパティを設定

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