OSDN Git Service

Sメーター周りを修正
[trx-305dsp/dsp.git] / trx305 / kernel / config / blackfin / _common_bf506 / chip_config.c
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  *
6  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  *
9  *  TOPPERS/JSP for Blackfin
10  *
11  *  Copyright (C) 2004,2006,2006 by Takemasa Nakamura
12  *  Copyright (C) 2004 by Ujinosuke
13  *  Copyright (C) 2010,2011 by Kaneko System Co., Ltd.
14  *
15  *  上記著作権者は,以下の (1)~(4) の条件か,Free Software Foundation
16  *  によって公表されている GNU General Public License の Version 2 に記
17  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
18  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
19  *  利用と呼ぶ)することを無償で許諾する.
20  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
21  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
22  *      スコード中に含まれていること.
23  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
24  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
25  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
26  *      の無保証規定を掲載すること.
27  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
28  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
29  *      と.
30  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
31  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
32  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
33  *        報告すること.
34  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
35  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
36  *
37  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
38  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
39  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
40  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
41  *
42  *
43  */
44
45 /*
46  *  ターゲットシステム依存モジュール(ADSP-BF506用)
47  */
48
49 #include "jsp_kernel.h"
50 #include <sil.h>
51
52 #ifdef __GNUC__
53 #include <cdefBF506F.h>     /* gnu tool chain */
54 #elif defined(__ECC__)
55 #include <cdefBF506F.h>             /* VisualDSP++ */
56 #include <ccblkfn.h>
57 #include <sysreg.h>
58 #else
59 #error "Compiler is not supported"
60 #endif
61
62
63 /*
64  *  ターゲットシステム依存の初期化
65  */
66 void
67 sys_initialize()
68 {
69     /*
70      * スプリアス割り込みハンドラの設定
71      *
72      * cpu_initialize()が行うダミーの割り込みハンドラの設定を上書きする。
73      * アプリケーションが割り込みハンドラを設定すると、以下の設定も上書き
74      * される。
75      */
76     int i;
77
78     for ( i=0; i<DEVICE_INTERRUPT_COUNT+3; i++ )
79         dev_vector[i] = &spurious_int_handler;
80
81     exc_vector = &spurious_exc_handler;
82
83     /*
84      *  PLLの設定
85      *
86      */
87     /*
88      *  SSELVAL, CSELVALはboard_config.hにて定義。FORCE_PLL_INITIALIZEはsys_config.hで
89      *  必要に応じて宣言する。
90      */
91 #ifndef FORCE_PLL_INITIALIZE
92         // PLLが初期値のままならPLLを初期化する
93     if ( *pPLL_CTL == 0x0c80 )
94 #endif
95     {
96         *pSIC_IWR = IWR_ENABLE(0);              // PLLのみIWRを許す
97 #if CSELVAL == 1
98         *pPLL_DIV = CSEL_DIV1 | SET_SSEL(SSELVAL);
99 #elif CSELVAL == 2
100         *pPLL_DIV = CSEL_DIV2 | SET_SSEL(SSELVAL);
101 #elif CSELVAL == 4
102         *pPLL_DIV = CSEL_DIV4 | SET_SSEL(SSELVAL);
103 #elif CSELVAL == 8
104         *pPLL_DIV = CSEL_DIV8 | SET_SSEL(SSELVAL);
105 #else
106 #error Wrong CSELVAL. Must be one of 1,2,4,8.
107 #endif
108                 // PLLの分周器に値を設定する
109         *pPLL_CTL = MSELVAL << 9;
110
111                 // PLLを起動する。
112         asm("cli r0; csync; idle; sti r0;": : :"R0");
113         *pSIC_IWR = IWR_ENABLE_ALL;
114     }
115
116     /*
117      *  UART分周比の設定
118      *
119      *  Logtaskが動作する前にsys_putc()を使うための設定を行う。以下の設定は
120      *  serial関連のタスクが起動したときに上書きされる。
121      */
122 #define DLAB 0x80
123
124         /* Blackfin 固有の設定。UARTイネーブル */
125     *pUART0_GCTL = 1;
126
127         /* クロックの設定 */
128     *pUART0_LCR |= DLAB;
129     *pUART0_DLL = UART0_DIVISOR & 0xFF ;
130     *pUART0_DLH = UART0_DIVISOR >> 8;
131     *pUART0_LCR &= ~DLAB;
132
133         /* モード設定, パリティ無し 8bit data, 1 stop bit */
134     *pUART0_LCR = 0x03;
135
136         /* 割込み禁止 */
137     *pUART0_IER_CLEAR = 0xFFFF;
138
139     *pPORTG_MUX &= ~(0x3000);   // bit13:12 だけを0にする
140     *pPORTG_FER |= 0x3000;      // PG12,PG13をUART0に割り振る
141
142 #if TNUM_SIOP_UART > 1
143     *pPORTF_MUX &= ~(0x00C0);   // bit7:6 だけを0にする
144     *pPORTF_FER |= 0x00C0;      // PF6,7をUART1に割り振る
145 #endif
146 }
147
148 /*
149  * priority_maskは、event順位0..15に応じた割り込み要求のビットマップを保持する。
150  * priority_mask[]のインデックスはevent順位と同じである。割り込み要因は BF51xでは
151  * 64要因あるので、unsigned long longによる64bit型としている。
152  *
153  * device_dispatch()はpriority_mask[]を参照して、現在起きたイベントがどの割り込み
154  * 要因であるか決定する助けとする。
155  *
156  * この変数はmake_priority_mask()を呼ぶ度に、実際のIARxの値に応じて上書きされる。
157  *
158  */
159 unsigned long long int priority_mask[16]={
160     0x0000000000000000ull,  /* EMU */
161     0x0000000000000000ull,  /* RST */
162     0x0000000000000000ull,  /* NMI */
163     0x0000000000000000ull,  /* EVX */
164     0x0000000000000000ull,
165     0x0000000000000000ull,  /* IVHW */
166     0x0000000000000000ull,  /* IVTMR */
167     0xFF680000000007FFull,  /* IVG7 */
168     0x0000000000003800ull,  /* IVG8 */
169     0x00000000000FC000ull,  /* IVG9 */
170     0x00F9000003F00000ull,  /* IVG10 */
171     0x00000000FC000000ull,  /* IVG11 */
172     0x000003FF00000000ull,  /* IVG12 */
173     0x00007C0000000000ull,  /* IVG13 */
174     0x0000000000000000ull,  /* IVG14 */
175     0x0000000000000000ull   /* IVG15 */
176 };
177
178
179 /*
180 * SIC_IARxを解析して、イベント順位ごとに割り当てられている割り込み
181 * のビットマップを作る。SIC_IARxのフィールド値は優先順位-7なので
182 * その分補正する。
183 */
184 #define INSTALL_PRIORITY    \
185     for ( i=0; i<8; i++ ){ \
186         priority = iar & 0xf;                         /* IARから優先順位を取り出す */ \
187         priority_mask[priority + 7] |= device;        /* 取り出した優先順位に基づきデバイスを登録 */ \
188         device <<= 1;                                 /* 次のデバイス */ \
189         iar >>= 4;                                    /* 次のIARフィールド */ \
190     }
191
192 /*
193 *  割り込み順位ごとのISRビットマップの作成SIC_IARxの設定はこの部分より前に済ませること。
194 *  この関数はuITRONのイニシャライザで使用することを想定しており、特に割り込みから保護していない。
195 */
196 void make_priority_mask( void )
197 {
198     unsigned int i, priority, iar;
199     unsigned long long int device;
200
201         // priority_maskは、event順位0..15に応じた割り込み要求のビットマップを保持する。
202         // 最初にクリアする
203     for ( i=0; i<16; i++ ){
204         priority_mask[i] = 0;
205     }
206
207     device = 1;
208     iar = *pSIC_IAR0;
209     INSTALL_PRIORITY
210
211     iar = *pSIC_IAR1;
212     INSTALL_PRIORITY
213
214     iar = *pSIC_IAR2;
215     INSTALL_PRIORITY
216
217     iar = *pSIC_IAR3;
218     INSTALL_PRIORITY
219
220     iar = *pSIC_IAR4;
221     INSTALL_PRIORITY
222
223     iar = *pSIC_IAR5;
224     INSTALL_PRIORITY
225
226     iar = *pSIC_IAR6;
227     INSTALL_PRIORITY
228 }
229
230
231 /*
232  * 割り込みの許可。ADSP-BF51xは効率的な割り込み処理と安全な割り込み禁止を両立する
233  * 手段を持たないため、禁止関数は置いていない。
234  *
235  * 不便ではあるが、プログラマに注意を促すためにそうしている。
236  */
237 ER ena_int( INTNO intno )
238 {
239     unsigned int mask;
240     SIL_PRE_LOC;
241
242     if ( intno >= DEVICE_INTERRUPT_COUNT )
243         return ( E_PAR );
244     else {
245         if ( intno < 32 ){
246             mask = 1 << intno;
247             SIL_LOC_INT();
248             *pSIC_IMASK0 |= mask;
249             asm volatile( "ssync;" );
250             SIL_UNL_INT();
251         }
252         else{
253             mask = 1 << (intno-32);
254             SIL_LOC_INT();
255             *pSIC_IMASK1 |= mask;
256             asm volatile( "ssync;" );
257             SIL_UNL_INT();
258         }
259         return (0);
260     }
261 }
262
263
264 /*
265  * 割り込みマスクの取得。ADSP-BF51xは効率的な割り込み処理と安全な割り込み禁止を両立する
266  * 手段を持たないため、禁止関数は置いていない。
267  *
268  * 不便ではあるが、プログラマに注意を促すためにそうしている。
269  */
270
271
272 extern ER get_ims( IMS * p_ims )
273 {
274     SIL_PRE_LOC;
275
276     SIL_LOC_INT();
277     *p_ims = (((IMS)*pSIC_IMASK1)<<32 ) | (IMS)*pSIC_IMASK0;
278     SIL_UNL_INT();
279     return( 0 );
280 }
281
282
283 /*
284  *  割り込みをデバイスに割り当てる。
285  *
286  *  この間数は割り込み発生時に共通割り込みハンドラの一部としてアセンブリ言語から割り込み禁止状態で
287  *  呼ばれる。実割り込みハンドラを割り込み可能にするため、asm文を使って途中で割り込み可能にしている。
288  *  割り込み禁止状態で呼ぶのは割り込み源の特定を安全におこなうためである。
289  *
290  */
291 void device_dispatcher( unsigned int priority, unsigned int imask )
292 {
293     unsigned int device, candidates;
294     unsigned long long int longcandidates, sic_isr, sic_imask;
295
296         // 以下では SIC_IMASK0,1をまとめて64bitレジスタとして扱っている。SIC_ISRも同じである。
297     get_ims(&sic_imask);
298     sic_isr = (((IMS)*pSIC_ISR1)<<32 ) | (IMS)*pSIC_ISR0;
299
300         // 現在のプライオリティに相当する割込み源を特定する。
301     longcandidates = priority_mask[priority] & sic_isr & sic_imask;
302
303     asm volatile("sti %0;": : "d"(imask) );
304
305     if ( ! longcandidates ) // 割り込み源が特定できないなら、コア由来である
306     {
307         if ( priority == ik_hardware_err)
308             dev_vector[INHNO_HW_ERROR]();
309         else
310             if ( priority == ik_timer)
311             dev_vector[INHNO_TIMER]();
312         else
313             dev_vector[INHNO_RAISE]();      // ソフトウェア割り込み
314
315     }
316     else if ( longcandidates & 0xFFFFFFFF00000000ull )
317     {
318         candidates = longcandidates >> 32;
319         if ( candidates & 0x80000000 )
320             device = 31;
321         else
322         {
323 #ifdef __GNUC__
324     asm ( "r1.L = signbits %1; %0 = r1.L(z);":"=d"(device) :"d"(candidates): "R1"  );
325 #elif defined(__ECC__)
326     asm( "%0 = signbits %1;" : "=l"( device ) : "d"( candidates ) );
327 #else
328 #error "Compiler is not supported"
329 #endif
330             device = 30 - device;       // bit mask is converted to bit number
331         }
332         dev_vector[device+32]();
333     }
334     else
335     {
336         candidates = (unsigned int)longcandidates;
337         if ( candidates & 0x80000000 )
338             device = 31;
339         else
340         {
341 #ifdef __GNUC__
342     asm ( "r1.L = signbits %1; %0 = r1.L(z);":"=d"(device) :"d"(candidates): "R1"  );
343 #elif defined(__ECC__)
344     asm( "%0 = signbits %1;" : "=l"( device ) : "d"( candidates ) );
345 #else
346 #error "Compiler is not supported"
347 #endif
348             device = 30 - device;       // bit mask is converted to bit number
349         }
350         dev_vector[device]();
351     }
352 }
353
354
355
356 /*
357  *  ターゲットシステムの終了。TOPPERS/JSPは対話型ROMモニタに戻ることを想定しているが、
358  *  このボードにROMはない。
359  */
360 void
361 sys_exit()
362 {
363     while(1)
364         ;
365 }
366
367 /*
368  *  ターゲットシステムの文字出力。割り込みが無効な状態でポーリングによる出力を行う。
369  */
370 void
371 sys_putc(char c)
372 {
373     if ( c== 0x0A )         /* もし LF ならば */
374         sys_putc( 0x0D );   /* CRを一文字送信 */
375
376     while( !( *pUART0_LSR & (1<<5)) )
377         ;       /* UART0 LSRのTHREが1になるまで待つ。1ならば送信レジスタ空き。*/
378
379     *pUART0_THR = c;    /* 一文字送信 */
380 }
381
382
383