source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/arch/rx630_gcc/prc_kernel_impl.h@ 337

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

ASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-chdr;charset=UTF-8
File size: 20.3 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 sil_wrb_mem(ier_reg_addr[intno].addr,
353 sil_reb_mem(ier_reg_addr[intno].addr) & ~ier_reg_addr[intno].offset);
354
355 return ( true );
356}
357
358
359/*
360 * 割込み要求禁止フラグのクリア
361 *
362 * 割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
363 * フラグをクリアしようとした場合には,FALSEを返す.
364 */
365Inline bool_t
366enable_int( INTNO intno )
367{
368 /*
369 * レベル定義が0である場合はCFG_INTされていない
370 */
371 if( cfg_int_table[intno].intpri == 0 ){
372 return ( false );
373 }
374
375 sil_wrb_mem(ier_reg_addr[intno].addr,
376 sil_reb_mem(ier_reg_addr[intno].addr) | ier_reg_addr[intno].offset);
377
378 return ( true );
379}
380
381
382/*
383 * 割込み要求がクリアできる状態か?
384 */
385Inline bool_t
386check_intno_clear(INTNO intno)
387{
388 return(true);
389}
390
391/*
392 * 割込み要求のクリア
393 */
394Inline void
395clear_int( INTNO intno )
396{
397 sil_wrb_mem(IR_REG(intno), 0U);
398}
399
400
401/*
402 * 割込みが要求できる状態か?
403 */
404Inline bool_t
405check_intno_raise(INTNO intno)
406{
407 return(true);
408}
409
410/*
411 * 割込みの要求
412 * 注意:チップでサポートされていない操作
413 */
414Inline void
415raise_int( INTNO intno )
416{
417 *IR_REG(intno) = 1U;
418}
419
420/*
421 * 割込み要求のチェック
422 */
423Inline bool_t
424probe_int( INTNO intno )
425{
426 /*
427 * 割込み要求レジスタは0 or 1でしかないため,
428 * そのままの値を返す.
429 */
430 return sil_reb_mem(IR_REG(intno));
431}
432
433/*
434 * 割込み要求ラインの属性の設定
435 */
436extern void config_int( INTNO intno, ATR intatr, PRI intpri );
437
438/*
439 * 割込みを受け付けるための遅延処理
440 */
441Inline void
442delay_for_interrupt(void)
443{
444}
445
446/*
447 * 最高優先順位タスクへのディスパッチ(prc_support.a30)
448 *
449 * dispatchは,タスクコンテキストから呼び出されたサービスコール処理か
450 * ら呼び出すべきもので,タスクコンテキスト・CPUロック状態・ディスパッ
451 * チ許可状態・(モデル上の)割込み優先度マスク全解除状態で呼び出さな
452 * ければならない.
453 */
454extern void dispatch( void );
455
456/*
457 * 非タスクコンテキストからのディスパッチ要求
458 */
459#define request_dispatch()
460
461/*
462 * ディスパッチャの動作開始(prc_support.a30)
463 *
464 * start_dispatchは,カーネル起動時に呼び出すべきもので,すべての割込
465 * みを禁止した状態(全割込みロック状態と同等の状態)で呼び出さなければ
466 * ならない.
467 */
468extern void start_dispatch( void ) NoReturn;
469
470/*
471 * 現在のコンテキストを捨ててディスパッチ(prc_support.a30)
472 *
473 * exit_and_dispatchは,ext_tskから呼び出すべきもので,タスクコンテキ
474 * スト・CPUロック状態・ディスパッチ許可状態・(モデル上の)割込み優先
475 * 度マスク全解除状態で呼び出さなければならない.
476 */
477#define _kernel_exit_and_dispatch(); \
478 _exit_and_dispatch(); \
479 ercd = E_SYS;
480
481extern void _exit_and_dispatch( void ) NoReturn;
482
483/*
484 * カーネルの終了処理の呼出し(prc_support.a30)
485 *
486 * call_exit_kernelは,カーネルの終了時に呼び出すべきもので,非タスク
487 * コンテキストに切り換えて,カーネルの終了処理(exit_kernel)を呼び出
488 * す.
489 */
490extern void call_exit_kernel( void ) NoReturn;
491
492/*
493 * タスクコンテキストの初期化
494 *
495 * タスクが休止状態から実行できる状態に移行する時に呼ばれる.この時点
496 * でスタック領域を使ってはならない.
497 *
498 * activate_contextを,インライン関数ではなくマクロ定義としているのは,
499 * この時点ではTCBが定義されていないためである.
500 */
501extern void start_r( void );
502
503#define activate_context( p_tcb ) \
504{ \
505 { \
506 \
507 /* スタックポインタ初期値の設定 */ \
508 ( p_tcb )->tskctxb.sp = ( void * )((( uint32_t ) ( p_tcb )->p_tinib->stk ) + \
509 ( p_tcb )->p_tinib->stksz ); \
510 /* 起動番地の設定 */ \
511 ( p_tcb )->tskctxb.pc = ( FP ) start_r; \
512 } \
513}
514
515
516/*
517 * calltexは使用しない
518 */
519#define OMIT_CALLTEX
520
521
522/*
523 * 割込みハンドラの設定
524 *
525 * RX630はROMに割込みベクタを配置するため,本関数は空関数で実装する.
526 */
527Inline void
528define_inh( INHNO inhno, FP inthdr )
529{
530}
531
532/*
533 * CPU例外ハンドラの設定
534 *
535 * RX630はROMに例外ベクタを配置するため,本関数は空関数で実装する.
536 */
537Inline void
538define_exc( EXCNO excno, FP exchdr )
539{
540}
541
542/*
543 * 割込み/例外ハンドラの入口処理の生成マクロ
544 *
545 * テンプレートファイルにより生成するため空マクロとする.
546 */
547#define HDR_ENTRY(hdr, intexc_num , tobejmp)
548
549/*
550 * 割込みハンドラの入口処理の生成マクロ
551 */
552#define _INT_ENTRY(inhno, inthdr) _kernel_##inthdr##_##inhno##_entry
553#define INT_ENTRY(inhno, inthdr) _INT_ENTRY(inhno , inthdr)
554
555#define _INTHDR_ENTRY(inhno, inhno_num ,inthdr) \
556 extern void _kernel_##inthdr##_##inhno##_entry(void);
557#define INTHDR_ENTRY(inhno, inhno_num ,inthdr) _INTHDR_ENTRY(inhno, inhno_num ,inthdr)
558
559
560/*
561 * CPU例外ハンドラの入口処理の生成マクロ
562 */
563#define _EXC_ENTRY(excno , exchdr) _kernel_##exchdr##_##excno##_entry
564#define EXC_ENTRY(excno , exchdr) _EXC_ENTRY(excno , exchdr)
565
566#define _EXCHDR_ENTRY(excno , excno_num , exchdr) \
567 extern void _kernel_##exchdr##_##excno##_entry(void);
568#define EXCHDR_ENTRY(excno , excno_num , exchdr) _EXCHDR_ENTRY(excno , excno_num , exchdr)
569
570
571/*
572 * CPU例外の発生した時のコンテキストの参照
573 *
574 * CPU例外の発生した時のコンテキストが,タスクコンテキストの時にFALSE,
575 * そうでない時にtrueを返す.
576 */
577Inline bool_t
578exc_sense_context( void *p_excinf )
579{
580 /*
581 * ネストカウンタが1より大なら非タスクコンテキスト
582 */
583 return( intnest > 1U );
584}
585
586#endif /* TOPPERS_MACRO_ONLY */
587
588/*
589 * CPU例外情報 p_excinf から PSW の値を取得するためのオフセット値
590 * EXCNO + ACC + FPSW + R1~R15 + PC
591 */
592#define EXC_GET_PSW_OFFSET (4+8+4+60+4)
593
594#ifndef TOPPERS_MACRO_ONLY
595
596/*
597 * CPU例外の発生した時のIPLの参照
598 */
599Inline uint32_t
600exc_get_ipl(void *p_excinf)
601{
602 return((*((uint32_t *)((uintptr_t)p_excinf+EXC_GET_PSW_OFFSET)))
603 & PSW_IPL_MASK);
604}
605
606Inline bool_t
607exc_sense_i(void *p_excinf)
608{
609 return((*(((uint32_t *)((uintptr_t)p_excinf+EXC_GET_PSW_OFFSET)))
610 & PSW_I_MASK) != 0u);
611}
612
613
614/*
615 * CPU例外の発生した時のコンテキストと割込みのマスク状態の参照
616 *
617 * CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコ
618 * ンテキストであり,全割込みロック状態でなく,CPUロック状態でなく,(モ
619 * デル上の)割込み優先度マスク全解除状態である時にtrue,そうでない時
620 * にFALSEを返す(CPU例外がカーネル管理外の割込み処理中で発生した場合
621 * にもFALSEを返す).
622 *
623 * カーネル実行中でない→ (TIPM_LOCK== -15) Iフラグ == 1
624 * (else) IPL < IPL_LOCK
625 * タスクコンテキストである→intnest == 0
626 * 全割込みロックでない→ Iフラグ == 1
627 * 割込み優先度マスクが全解除→IPL == 0
628 *
629 *
630 */
631Inline bool_t
632exc_sense_intmask(void *p_excinf)
633{
634 return((!exc_sense_context(p_excinf))
635 && exc_sense_i(p_excinf)
636 && (exc_get_ipl(p_excinf) == IPL_ENAALL));
637}
638
639/*
640 * CPU例外の発生した時のコンテキストと割込み/CPUロック状態の参照
641 *
642 * CPU例外の発生した時のシステム状態が,カーネル実行中でなく,タスクコ
643 * ンテキストであり,全割込みロック状態でなく,CPUロック状態でない時に
644 * true,そうでない時にfalseを返す(CPU例外がカーネル管理外の割込み処
645 * 理中で発生した場合にもfalseを返す).
646 *
647 * カーネル実行中でない→ (TIPM_LOCK== -15) Iフラグ == 1
648 * (else) IPL < TIPM_LOCK
649 * タスクコンテキストである→intnest < 1
650 * 全割込みロックでない→ Iフラグ == 1
651 * CPUロック状態でない→(TIPM_LOCK== -15) Iフラグ == 1
652 * (else) IPL < TIPM_LOCK
653 */
654Inline bool_t
655exc_sense_unlock(void *p_excinf)
656{
657#if TIPM_LOCK == -15
658 return((!exc_sense_context(p_excinf))
659 && exc_sense_i(p_excinf));
660#else
661 return((!exc_sense_context(p_excinf))
662 && exc_sense_i(p_excinf)
663 && exc_get_ipl(p_excinf) < IPL_LOCK);
664#endif
665}
666
667
668/*
669 * プロセッサ依存の初期化
670 */
671extern void prc_initialize( void );
672
673/*
674 * プロセッサ依存の終了時処理
675 */
676extern void prc_terminate( void );
677
678
679#ifndef OMIT_DEFAULT_INT_HANDLER
680/*
681 * 未登録の割込みが発生した場合に呼び出される
682 */
683void default_int_handler( void );
684#endif /* OMIT_DEFAULT_INT_HANDLER */
685
686#ifndef OMIT_DEFAULT_EXC_HANDLER
687/*
688 * 未登録の例外が発生した場合に呼び出される
689 */
690void default_exc_handler( void );
691#endif /* OMIT_DEFAULT_EXC_HANDLER */
692
693
694#endif /* TOPPERS_MACRO_ONLY */
695
696#endif /* TOPPERS_PRC_CONFIG_H */
697
Note: See TracBrowser for help on using the repository browser.