OSDN Git Service

チケット #25999 「SIOポートのピン割り当ての変更」に対応。TOP
[toppersasp4lpc/asp.git] / asp / arch / arm_m_gcc / common / core_config.c
1 /*
2  *  TOPPERS/ASP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Advanced Standard Profile Kernel
5  * 
6  *  Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
7  *              Graduate School of Information Science, Nagoya Univ., JAPAN
8  * 
9  *  上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
10  *  ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11  *  変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
12  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14  *      スコード中に含まれていること.
15  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18  *      の無保証規定を掲載すること.
19  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
21  *      と.
22  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
23  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
24  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
25  *        報告すること.
26  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
27  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
28  *      また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
29  *      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
30  *      免責すること.
31  * 
32  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
34  *  に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
35  *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
36  *  の責任を負わない.
37  * 
38  *  @(#) $Id: core_config.c 2193 2011-07-25 04:34:11Z ertl-honda $
39  */
40
41 /*
42  *              コア依存モジュール(ARM-M用)
43  */
44
45 #include "kernel_impl.h"
46 #include "check.h"
47 #include "task.h"
48
49 /*
50  *  CPUロックフラグ実現のための変数
51  */
52 volatile bool_t         lock_flag;              /* CPUロックフラグの値を保持する変数 */
53 volatile uint32_t       saved_iipm;             /* 割込み優先度マスクを保存する変数 */
54
55 /*
56  *  ベクタテーブル(kernel_cfg.c)
57  */
58 extern const FP vector_table[];
59
60 /*
61  *  システム例外・割込みの(例外番号 4〜15)
62  *  割込み優先度設定レジスタへのアクセスのための配列
63  */
64 static const unsigned int nvic_sys_pri_reg[] = {
65         0,
66         NVIC_SYS_PRI1,
67         NVIC_SYS_PRI2,
68         NVIC_SYS_PRI3
69 };
70
71 /*
72  *  例外と割込みの割込み優先度をセット
73  *
74  *  excnoはARM-Mで定められている Exception Number を指定.
75  */
76 void
77 set_exc_int_priority(uint32_t excno, uint32_t iipm){
78         uint32_t tmp, reg;
79
80         /*
81          *  割込み優先度設定レジスタの決定
82          */
83         if ((EXCNO_MPU <= excno) && (excno <= IRQNO_SYSTICK)) {
84                 /*
85                  * Exception Number 4(Memory Management)から
86                  * Exception Number 15(SysTick)までの割込み優先度はシステム優先度
87                  * レジスタにより設定.
88                  */
89                 reg = nvic_sys_pri_reg[excno >> 2];
90         }
91         else if ((TMIN_INTNO < excno) && (excno <= TMAX_INTNO)){
92                 /*
93                  * IRQ割込みなら
94                  */
95                 reg = NVIC_PRI0 + (((excno - (TMIN_INTNO + 1)) >> 2) * 4);
96         }
97         else {
98                 return ;
99         }
100         
101         tmp = sil_rew_mem((void *)reg);
102         tmp &= ~(0xFF << (8 * (excno & 0x03)));
103         tmp |= iipm << (8 * (excno & 0x03));
104         sil_wrw_mem((void *)reg, tmp);
105 }
106
107 /*
108  *  例外の許可
109  *
110  *  Memory Management, Bus Fault, Usage Fault は禁止・許可が可能
111  */
112 void
113 enable_exc(EXCNO excno)
114 {
115         uint32_t tmp;
116
117         switch (excno) {
118           case EXCNO_MPU:
119                 tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
120                 tmp |= NVIC_SYS_HND_CTRL_MEM;
121                 sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
122                 break;
123           case EXCNO_BUS:
124                 tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
125                 tmp |= NVIC_SYS_HND_CTRL_BUS;
126                 sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
127                 break;
128           case EXCNO_USAGE:
129                 tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
130                 tmp |= NVIC_SYS_HND_CTRL_USAGE;
131                 sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
132                 break;
133         }
134 }
135
136 /*
137  *  例外の禁止
138  */
139 void
140 disable_exc(EXCNO excno)
141 {
142         uint32_t tmp;
143
144         switch (excno) {
145           case EXCNO_MPU:
146                 tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
147                 tmp &= ~NVIC_SYS_HND_CTRL_MEM;
148                 sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
149                 break;
150           case EXCNO_BUS:
151                 tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
152                 tmp &= ~NVIC_SYS_HND_CTRL_BUS;
153                 sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
154                 break;
155           case EXCNO_USAGE:
156                 tmp = sil_rew_mem((void *)NVIC_SYS_HND_CTRL);
157                 tmp &= ~NVIC_SYS_HND_CTRL_USAGE;
158                 sil_wrw_mem((void *)NVIC_SYS_HND_CTRL, tmp);
159                 break;
160         }
161 }
162
163
164 /*
165  *  コア依存の初期化
166  */
167 void
168 core_initialize(void)
169 {
170         /*
171          *  CPUロックフラグ実現のための変数の初期化
172          */
173         lock_flag = true;
174         saved_iipm = IIPM_ENAALL;
175
176         /*
177          *  ベクタテーブルを設定
178          */
179         sil_wrw_mem((void*)NVIC_VECTTBL, (uint32_t)vector_table);
180
181         /*
182          *  各例外の優先度を設定
183          *  CPUロック状態でも発生するように,BASEPRIレジスタでマスクでき
184          *  ない'0'とする.
185          */
186         set_exc_int_priority(EXCNO_HARD, 0);
187         set_exc_int_priority(EXCNO_MPU, 0);
188         set_exc_int_priority(EXCNO_BUS, 0);
189         set_exc_int_priority(EXCNO_USAGE, 0);
190         set_exc_int_priority(EXCNO_SVCALL, 0);
191         set_exc_int_priority(EXCNO_DEBUG, 0);
192         set_exc_int_priority(EXCNO_PENDSV, 0);
193
194         /*
195          *  SVCハンドラを有効に
196          */
197         x_enable_int(EXCNO_SVCALL);
198 }
199
200 /*
201  *  コア依存の終了処理
202  */
203 void
204 core_terminate(void)
205 {
206         extern void    software_term_hook(void);
207         void (*volatile fp)(void) = software_term_hook;
208
209         /*
210          *  software_term_hookへのポインタを,一旦volatile指定のあるfpに代
211          *  入してから使うのは,0との比較が最適化で削除されないようにするた
212          *  めである.
213          */
214         if (fp != 0) {
215                 (*fp)();
216         }
217 }
218
219 /*
220  *  割込み要求ライン属性の設定
221  */
222 void
223 x_config_int(INTNO intno, ATR intatr, PRI intpri)
224 {
225         assert(VALID_INTNO_CFGINT(intno));
226         assert(TMIN_INTPRI <= intpri && intpri <= TMAX_INTPRI);
227
228         /* 
229          *  一旦割込みを禁止する
230          */    
231         (void)x_disable_int(intno);
232
233         /*
234          *  割込み優先度をセット
235          */
236         set_exc_int_priority(intno, INT_IPM(intpri));
237
238         /*
239          *  割込み要求マスク解除(必要な場合)
240          */
241         if ((intatr & TA_ENAINT) != 0U) {
242                 (void) x_enable_int(intno);
243         }    
244 }
245
246
247 #ifndef OMIT_DEFAULT_EXC_HANDLER
248 /*
249  *  Trapa以外の例外で登録されていない例外が発生すると呼び出される
250  */
251 void
252 default_exc_handler(void *p_excinf)
253 {
254         uint32_t basepri = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_BASEPRI);
255         uint32_t pc      = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_PC);
256         uint32_t xpsr    = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_XPSR);
257         uint32_t excno   = get_ipsr() & IPSR_ISR_NUMBER;
258
259         syslog(LOG_EMERG, "\nUnregistered Exception occurs.");
260         syslog(LOG_EMERG, "Excno = %08x PC = %08x XPSR = %08x basepri = %08X, p_excinf = %08X",
261                    excno, pc, xpsr, basepri, p_excinf);
262
263         target_exit();
264 }
265 #endif /* OMIT_DEFAULT_EXC_HANDLER */
266
267 #ifndef OMIT_DEFAULT_INT_HANDLER
268 /*
269  *  未登録の割込みが発生した場合に呼び出される
270  */
271 void
272 default_int_handler(void *p_excinf)
273 {
274         uint32_t basepri = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_BASEPRI);
275         uint32_t pc      = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_PC);
276         uint32_t xpsr    = *(((uint32_t*)p_excinf) + P_EXCINF_OFFSET_XPSR);
277         uint32_t excno   = get_ipsr() & IPSR_ISR_NUMBER;
278
279         syslog(LOG_EMERG, "\nUnregistered Interrupt occurs.");
280         syslog(LOG_EMERG, "Excno = %08x PC = %08x XPSR = %08x basepri = %08X, p_excinf = %08X",
281                    excno, pc, xpsr, basepri, p_excinf);
282
283         target_exit();
284 }
285 #endif /* OMIT_DEFAULT_INT_HANDLER */