source: ssp_qb_r5f100le_cs/trunk/arch/arm_m_gcc/prc_config.h

Last change on this file was 95, checked in by nmir-saito, 9 years ago

ファイルの mime-type 変更

  • Property svn:mime-type set to text/plain; charset=shift_jis
File size: 13.8 KB
Line 
1/*
2 * TOPPERS/SSP Kernel
3 * Smallest Set Profile Kernel
4 *
5 * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
6 * Graduate School of Information Science, Nagoya Univ., JAPAN
7 * Copyright (C) 2015 by Naoki Saito
8 * Nagoya Municipal Industrial Research Institute, JAPAN
9 *
10 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
13 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15 * スコード中に含まれていること.
16 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
18 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
19 * の無保証規定を掲載すること.
20 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
21 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
22 * と.
23 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
24 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
25 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
26 * 報告すること.
27 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
28 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
29 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
30 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
31 * 免責すること.
32 *
33 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
35 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
36 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
37 * の責任を負わない.
38 *
39 * @(#) $Id: prc_config.h 1304 2008-08-27 07:28:36Z ertl-honda $
40 */
41
42/*
43 * プロセッサ依存モジュール(ARM-M用)
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
60/*
61 * 非タスクコンテキスト用のスタック初期値
62 */
63#define TOPPERS_ISTKPT(istk, istksz) ((STK_T *)((char *)(istk) + (istksz)))
64
65#endif /* TOPPERS_MACRO_ONLY */
66
67#ifndef TOPPERS_MACRO_ONLY
68
69/*
70 * 割込みネスト数
71 */
72extern uint8_t intnest;
73
74/*
75 * コンテキストの参照
76 *
77 */
78Inline bool_t
79sense_context(void)
80{
81 bool_t tskctx;
82
83 if (intnest == 0u){
84 tskctx = false;
85 }
86 else {
87 tskctx = true;
88 }
89
90 return tskctx;
91}
92
93#endif /* TOPPERS_MACRO_ONLY */
94
95/*
96 * TOPPERS標準割込み処理モデルの実現
97 *
98 * 割込み優先度マスクとしては,BASEPRIを用いる.全割込みを禁止する
99 * 機能として,FAULTMASKやPRIMASKがあるが,カーネル管理外の割込みを
100 * サポートするため,これらはCPUロックのために用いない.
101 * そのため,BASEPRIを用いて擬似的にCPUロックフラグを実現する.
102 *
103 * まず,CPUロック状態を管理すための変数(lock_flag)を用意する.
104 *
105 * CPUロックフラグがクリアされている間は,BASEPRIをモデル上の割込み
106 * 優先度マスクの値に設定する.この間は,モデル上の割込み優先度マス
107 * クは,BASEPRIを用いる.
108 *
109 * それに対してCPUロックフラグがセットされいる間は,BASEPRIを,カーネ
110 * ル管理外のものを除くすべての割込み要求をマスクする値(TIPM_LOCK)と,
111 * モデル上の割込み優先度マスクとの高い方に設定する.この間のモデル上
112 * の割込み優先度マスクは,そのための変数(saved_iipm, 内部表現で保持)
113 * を用意して保持する.
114 */
115
116/*
117 * 割込み優先度マスクの外部表現と内部表現の変換
118 *
119 * アセンブリ言語のソースファイルからインクルードする場合のために,
120 * CASTを使用
121 * 割込み優先度のビット幅(TBITW_IPRI)が 8 の場合は,内部優先度 255
122 * は,外部優先度 -1 に対応する.
123 */
124#define EXT_IPM(iipm) (CAST(PRI,((iipm >> (8 - TBITW_IPRI)) - (1 << TBITW_IPRI)))) /* 内部表現を外部表現に */
125#define INT_IPM(ipm) (((1 << TBITW_IPRI) - CAST(uint8_t, -(ipm))) << (8 - TBITW_IPRI)) /* 外部表現を内部表現に */
126
127/*
128 * CPUロック状態での割込み優先度マスク
129 */
130#define TIPM_LOCK TMIN_INTPRI
131
132/*
133 * CPUロック状態での割込み優先度マスクの内部表現
134 *
135 * TIPM_LOCKは,CPUロック状態でのBASEPRIの値.カーネル管理外のものを
136 * 除くすべての割込みをマスクする値に定義する.
137 */
138#define IIPM_LOCK INT_IPM(TIPM_LOCK)
139
140/*
141 * TIPM_ENAALL(割込み優先度マスク全解除)の内部表現
142 *
143 * BASEPRIに '0' を設定することで,全割込みを許可する.
144 */
145#define IIPM_ENAALL (0)
146
147
148#ifndef TOPPERS_MACRO_ONLY
149
150/*
151 * CPUロックフラグ実現のための変数
152 *
153 * これらの変数は,CPUロック状態の時のみ書き換えてもよいとする.
154 * インライン関数中で,アクセスの順序が変化しないよう,volatile を指定.
155 */
156extern volatile bool_t lock_flag; /* CPUロックフラグの値を保持する変数 */
157extern volatile uint32_t saved_iipm; /* 割込み優先度をマスクする変数 */
158
159/*
160 * CPUロック状態への移行
161 *
162 * BASEPRI(ハードウェアの割込み優先度マスク)を,saved_iipmに保存し,
163 * カーネル管理外のものを除くすべての割込みをマスクする値(TIPM_LOCK)
164 * に設定する.また,lock_flagをtrueにする.
165 *
166 * BASEPRIが,最初からTIPM_LOCKと同じかそれより高い場合には,それを
167 * saved_iipmに保存するのみで,TIPM_LOCKには設定しない.これは,モデル
168 * 上の割込み優先度マスクが,TIPM_LOCKと同じかそれより高いレベルに設定
169 * されている状態にあたる.
170 *
171 * この関数は,CPUロック状態(lock_flagがtrueの状態)で呼ばれることは
172 * ないものと想定している.
173 */
174Inline void
175x_lock_cpu(void)
176{
177 uint32_t iipm;
178
179 /*
180 * current_iipm()の返り値を直接saved_iipmに保存せず,一時変数iipm
181 * を用いているのは,current_iipm()を呼んだ直後に割込みが発生し,
182 * 起動された割込み処理でsaved_iipmが変更される可能性があるためで
183 * ある.
184 */
185 iipm = get_basepri();
186 set_basepri(IIPM_LOCK);
187 saved_iipm = iipm;
188 lock_flag = true;
189 /* クリティカルセクションの前後でメモリが書き換わる可能性がある */
190 Asm("":::"memory");
191}
192
193#define t_lock_cpu() x_lock_cpu()
194#define i_lock_cpu() x_lock_cpu()
195
196/*
197 * CPUロック状態の解除
198 *
199 * lock_flagをfalseにし,IPM(ハードウェアの割込み優先度マスク)を,
200 * saved_iipmに保存した値に戻す.
201 *
202 * この関数は,CPUロック状態(lock_flagがtrueの状態)でのみ呼ばれるも
203 * のと想定している.
204 */
205Inline void
206x_unlock_cpu(void)
207{
208 /* クリティカルセクションの前後でメモリが書き換わる可能性がある */
209 Asm("":::"memory");
210 lock_flag = false;
211 set_basepri(saved_iipm);
212}
213
214#define t_unlock_cpu() x_unlock_cpu()
215#define i_unlock_cpu() x_unlock_cpu()
216
217/*
218 * CPUロック状態の参照
219 */
220Inline bool_t
221x_sense_lock(void)
222{
223 return(lock_flag);
224}
225
226#define t_sense_lock() x_sense_lock()
227#define i_sense_lock() x_sense_lock()
228
229
230/*
231 * (モデル上の)割込み優先度マスクの設定
232 *
233 * CPUロックフラグがクリアされている時は,ハードウェアの割込み優先度マ
234 * スクを設定する.CPUロックフラグがセットされている時は,saved_iipm
235 * を設定し,さらに,ハードウェアの割込み優先度マスクを,設定しようと
236 * した(モデル上の)割込み優先度マスクとTIPM_LOCKの高い方に設定する.
237 */
238Inline void
239x_set_ipm(PRI intpri)
240{
241 uint8_t iipm = INT_IPM(intpri);
242
243 if (intpri == TIPM_ENAALL){
244 iipm = IIPM_ENAALL;
245 }
246
247 if (!lock_flag) {
248 set_basepri(iipm);
249 }
250 else {
251 saved_iipm = iipm;
252 set_basepri(iipm < IIPM_LOCK ? iipm : IIPM_LOCK);
253 }
254}
255
256#define t_set_ipm(intpri) x_set_ipm(intpri)
257#define i_set_ipm(intpri) x_set_ipm(intpri)
258
259/*
260 * (モデル上の)割込み優先度マスクの参照
261 *
262 * CPUロックフラグがクリアされている時はハードウェアの割込み優先度マ
263 * スクを,セットされている時はsaved_iipmを参照する.
264 */
265Inline PRI
266x_get_ipm(void)
267{
268 uint8_t iipm;
269
270 if (!lock_flag) {
271 iipm = get_basepri();
272 }
273 else {
274 iipm = saved_iipm;
275 }
276
277 if (iipm == IIPM_ENAALL) {
278 return(TIPM_ENAALL);
279 }
280 else {
281 return(EXT_IPM(iipm));
282 }
283}
284
285#define t_get_ipm() x_get_ipm()
286#define i_get_ipm() x_get_ipm()
287
288/*
289 * SVCハンドラ(prc_support.S)
290 */
291extern void svc_handler(void);
292
293/*
294 * スタートアップルーチン(start.S)
295 */
296extern void _start(void);
297
298/*
299 * ディスパッチャの動作開始(prc_support.S)
300 *
301 * start_dispatchは,カーネル起動時に呼び出すべきもので,すべての割込
302 * みを禁止した状態(割込みロック状態と同等の状態)で呼び出さなければ
303 * ならない.
304 */
305extern void start_dispatch(void) NoReturn;
306
307
308/*
309 * カーネルの終了処理の呼出し(prc_support.S)
310 *
311 * call_exit_kernelは,カーネルの終了時に呼び出すべきもので,非タスク
312 * コンテキストに切り換えて,カーネルの終了処理(exit_kernel)を呼び出
313 * す.
314 */
315extern void call_exit_kernel(void) NoReturn;
316
317/*
318 * アイドルループの実装
319 *
320 * 単にCPUロック状態とCPUロック解除状態を呼び出す実装とする.
321 * スリープモードに入れる場合は本処理をwfi命令を用いて書き換えれば良い.
322 */
323Inline void
324idle_loop(void)
325{
326 lock_flag = false;
327 /* CPUアンロック => CPUロック */
328 Asm("\tmsr BASEPRI , %0" : : "r"(0) : "memory");
329 Asm("\tmsr BASEPRI , %0" : : "r"(IIPM_LOCK) : "memory");
330 lock_flag = true;
331}
332
333/*
334 * 割込み番号・割込みハンドラ番号
335 *
336 * 割込みハンドラ番号(inhno)と割込み番号(intno)は,割り込み発生時に
337 * EPSRに設定される例外番号とする.
338 */
339
340/*
341 * 割込み番号の範囲の判定
342 */
343#define VALID_INTNO(intno) ((TMIN_INTNO <= (intno)) && ((intno) <= TMAX_INTNO))
344#define VALID_INTNO_DISINT(intno) VALID_INTNO(intno)
345#define VALID_INTNO_CFGINT(intno) VALID_INTNO(intno)
346
347/*
348 * 割込みハンドラの設定
349 *
350 * ベクトル番号inhnoの割込みハンドラの起動番地int_entryに設定する.割込み
351 * ハンドラテーブル
352 */
353Inline void
354x_define_inh(INHNO inhno, FP int_entry)
355{
356 /* 特に行う処理はない */
357}
358
359/*
360 * 割込みハンドラの出入口処理の生成マクロ
361 *
362 */
363#define INT_ENTRY(inhno, inthdr) inthdr
364#define INTHDR_ENTRY(inhno, inhno_num, inthdr) extern void inthdr(void);
365
366/*
367 * 割込み要求禁止フラグ
368 */
369
370/*
371 * 割込み属性が設定されているかを判別するための変数(kernel_cfg.c)
372 */
373extern const uint32_t bitpat_cfgint[];
374
375/*
376 * 割込み要求禁止フラグのセット
377 *
378 * 割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
379 * フラグをクリアしようとした場合には,falseを返す.
380 */
381Inline bool_t
382x_disable_int(INTNO intno)
383{
384 uint32_t tmp;
385
386 /*
387 * 割込み属性が設定されていない場合
388 */
389 if ((bitpat_cfgint[intno >> 5] & (1 << (intno & 0x1f))) == 0x00) {
390 return(false);
391 }
392
393 if (intno == IRQNO_SYSTICK) {
394 tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
395 tmp &= ~SYSTIC_TICINT;
396 sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
397 }else {
398 tmp = intno - 16;
399 sil_wrw_mem((void *)NVIC_CLRENA0 + (tmp >> 5), (1 << (tmp & 0x1f)));
400 }
401
402 return(true);
403}
404
405#define t_disable_int(intno) x_disable_int(intno)
406#define i_disable_int(intno) x_disable_int(intno)
407
408/*
409 * 割込み要求禁止フラグの解除
410 *
411 * 割込み属性が設定されていない割込み要求ラインに対して割込み要求禁止
412 * フラグをクリアしようとした場合には,falseを返す.
413 */
414Inline bool_t
415x_enable_int(INTNO intno)
416{
417 uint32_t tmp;
418
419 /*
420 * 割込み属性が設定されていない場合
421 */
422 if ((bitpat_cfgint[intno >> 5] & (1 << (intno & 0x1f))) == 0x00) {
423 return(false);
424 }
425
426 if (intno == IRQNO_SYSTICK) {
427 tmp = sil_rew_mem((void *)SYSTIC_CONTROL_STATUS);
428 tmp |= SYSTIC_TICINT;
429 sil_wrw_mem((void *)SYSTIC_CONTROL_STATUS, tmp);
430 }else {
431 tmp = intno - 16;
432 sil_wrw_mem((void *)((uint32_t *)NVIC_SETENA0 + (tmp >> 5)),
433 (1 << (tmp & 0x1f)));
434 }
435
436 return(true);
437}
438
439#define t_enable_int(intno) x_enable_int(intno)
440#define i_enable_int(intno) x_enable_int(intno)
441
442Inline void
443x_clear_int(INTNO intno)
444{
445 uint32_t tmp;
446
447 if (intno != IRQNO_SYSTICK) {
448 tmp = intno - 16;
449 sil_wrw_mem((void *)((uint32_t *)NVIC_CLRENA0 + (tmp >> 5)),
450 (1 << (tmp & 0x1f)));
451 }
452}
453
454/*
455 * 割込み要求ラインの属性の設定
456 */
457extern void x_config_int(INTNO intno, ATR intatr, PRI intpri);
458
459/*
460 * 割込みハンドラ入口で必要なIRC操作
461 */
462Inline void
463i_begin_int(INTNO intno)
464{
465 /* 特に行う処理はない */
466}
467
468/*
469 * 割込みハンドラの出口で必要なIRC操作
470 */
471Inline void
472i_end_int(INTNO intno)
473{
474 /* 特に行う処理はない */
475}
476
477/*
478 * CPU例外ハンドラ関係
479 */
480
481/*
482 * CPU例外ハンドラ番号
483 */
484#define VALID_EXCNO_DEFEXC(excno) (TMIN_EXCNO <= (excno) && (excno) <= TMAX_EXCNO)
485
486/*
487 * CPU例外ハンドラの許可
488 */
489extern void enable_exc(EXCNO excno);
490
491/*
492 * CPU例外ハンドラの禁止
493 */
494extern void disable_exc(EXCNO excno);
495
496/*
497 * CPU例外ハンドラの設定
498 */
499Inline void
500x_define_exc(EXCNO excno, FP exc_entry)
501{
502 /*
503 * 一部の例外は許可を行う必要がある
504 */
505 enable_exc(excno);
506}
507
508/*
509 * CPU例外ハンドラの入口処理の生成マクロ
510 */
511#define EXC_ENTRY(excno, exchdr) exchdr
512#define EXCHDR_ENTRY(excno, excno_num, exchdr) extern void exchdr(void *p_excinf);
513
514
515/*
516 * CPU例外エントリ(prc_support.S)
517 */
518extern void exc_entry(void);
519
520/*
521 * 割込みエントリ(prc_support.S)
522 */
523extern void int_entry(void);
524
525/*
526 * プロセッサ依存の初期化
527 */
528extern void prc_initialize(void);
529
530/*
531 * プロセッサ依存の終了時処理
532 */
533extern void prc_terminate(void) NoReturn;
534
535/*
536 * atexitの処理とデストラクタの実行
537 */
538Inline void
539call_atexit(void)
540{
541 extern void software_term_hook(void);
542 void (*volatile fp)(void) = software_term_hook;
543
544 /*
545 * software_term_hookへのポインタを,一旦volatile指定のあるfpに代
546 * 入してから使うのは,0との比較が最適化で削除されないようにするた
547 * めである.
548 */
549 if (fp != 0) {
550 (*fp)();
551 }
552}
553
554/*
555 * 登録されていない例外が発生すると呼び出される
556 */
557extern void default_exc_handler(void *p_excinf);
558
559/*
560 * 未登録の割込みが発生した場合に呼び出される
561 */
562extern void default_int_handler(void *p_excinf);
563
564#endif /* TOPPERS_MACRO_ONLY */
565#endif /* TOPPERS_PRC_CONFIG_H */
Note: See TracBrowser for help on using the repository browser.