OSDN Git Service

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