OSDN Git Service

33ad587c988cb898413604f12d4ed23a0fab0898
[trx-305dsp/dsp.git] / trx305 / kernel / config / blackfin / _common_bf548 / 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-BF548用)
47  */
48
49 #include "jsp_kernel.h"
50 #include <sil.h>
51
52 #ifdef __GNUC__
53 #include <cdefBF548.h>      /* gnu tool chain */
54 #elif defined(__ECC__)
55 #include <cdefbf548.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  *  ターゲットシステム依存の初期化
67  */
68 void
69 sys_initialize()
70 {
71     /*
72      * スプリアス割り込みハンドラの設定
73      *
74      * cpu_initialize()が行うダミーの割り込みハンドラの設定を上書きする。
75      * アプリケーションが割り込みハンドラを設定すると、以下の設定も上書き
76      * される。
77      */
78     int i;
79
80     for ( i=0; i<DEVICE_INTERRUPT_COUNT+3; i++ )
81         dev_vector[i] = &spurious_int_handler;
82
83     exc_vector = &spurious_exc_handler;
84
85     /*
86      *  PLLの設定
87      *
88      */
89     /*
90      *  SSELVAL, CSELVALはboard_config.hにて定義。FORCE_PLL_INITIALIZEはsys_config.hで
91      *  必要に応じて宣言する。
92      */
93 #ifndef FORCE_PLL_INITIALIZE
94         // PLLが初期値のままであり、かつ、DDR-SDRAMが利用中でなければPLLを初期化する
95      if ( ( *pPLL_CTL == 0x1000 ) && ( !(*pEBIU_RSTCTL & DDRSRESET ) ) )
96 #endif
97      {
98
99         *pSIC_IWR0 = IWR_ENABLE(0);             // PLLのみIWRを許す
100 #if CSELVAL == 1
101         *pPLL_DIV = CSEL_DIV1 | SET_SSEL(SSELVAL);
102 #elif CSELVAL == 2
103         *pPLL_DIV = CSEL_DIV2 | SET_SSEL(SSELVAL);
104 #elif CSELVAL == 4
105         *pPLL_DIV = CSEL_DIV4 | SET_SSEL(SSELVAL);
106 #elif CSELVAL == 8
107         *pPLL_DIV = CSEL_DIV8 | SET_SSEL(SSELVAL);
108 #else
109 #error Wrong CSELVAL. Must be one of 1,2,4,8.
110 #endif
111                 // PLLの分周器に値を設定する
112         *pPLL_CTL = MSELVAL << 9;
113
114                 // PLLを起動する。
115         asm("cli r0; csync; idle; sti r0;": : :"R0");
116         *pSIC_IWR0 = IWR_ENABLE_ALL;
117     }
118
119     /*
120      *  UART分周比の設定
121      *
122      *  Logtaskが動作する前にsys_putc()を使うための設定を行う。以下の設定は
123      *  serial関連のタスクが起動したときに上書きされる。
124      */
125 #define DLAB 0x80
126 #if 0
127     /* Blackfin 固有の設定。UART0イネーブル */
128     *pUART0_GCTL = 1;
129
130         /* クロックの設定 */
131     *pUART0_LCR |= DLAB;
132     *pUART0_DLL = UART0_DIVISOR & 0xFF ;
133     *pUART0_DLH = UART0_DIVISOR >> 8;
134     *pUART0_LCR &= ~DLAB;
135
136         /* モード設定, パリティ無し 8bit data, 1 stop bit */
137     *pUART0_LCR = 0x03;
138
139         /* 割込み禁止 */
140     *pUART0_IER_CLEAR = 0xFFFF;
141
142     *pPORTH_MUX &= ~(0x0003C000);   // bit3:0 だけを0にする
143     *pPORTH_FER |= 0x0180;      // PE7,PE8をUART0に割り振る
144 #else
145     /* Blackfin 固有の設定。UART1イネーブル */
146     *pUART1_GCTL = 1;
147
148         /* クロックの設定 */
149     *pUART1_LCR |= DLAB;
150     *pUART1_DLL = UART1_DIVISOR & 0xFF ;
151     *pUART1_DLH = UART1_DIVISOR >> 8;
152     *pUART1_LCR &= ~DLAB;
153
154         /* モード設定, パリティ無し 8bit data, 1 stop bit */
155     *pUART1_LCR = 0x03;
156
157         /* 割込み禁止 */
158     *pUART1_IER_CLEAR = 0xFFFF;
159
160     *pPORTH_MUX &= ~(0x000F);   // bit3:0 だけを0にする
161     *pPORTH_FER |= 0x0003;      // PH0,PH1をUART1に割り振る
162 #endif
163 }
164
165 /*
166  * priority_maskは、event順位0..15に応じた割り込み要求のビットマップを保持する。
167  * priority_mask[]のインデックスはevent順位と同じである。割り込み要因は BF54xでは
168  * 96要因あるので、unsigned int型の3個の配列による96bit型としている。
169  * (chip_config.hのIMSの定義参照)
170  *
171  * device_dispatch()はpriority_mask[]を参照して、現在起きたイベントがどの割り込み
172  * 要因であるか決定する助けとする。
173  *
174  * この変数はmake_priority_mask()を呼ぶ度に、実際のIARxの値に応じて上書きされる。
175  *
176  */
177 IMS priority_mask[16]={
178     {0x00000000u, 0x00000000u, 0x00000000u},    /* EMU */
179     {0x00000000u, 0x00000000u, 0x00000000u},    /* RST */
180     {0x00000000u, 0x00000000u, 0x00000000u},    /* NMI */
181     {0x00000000u, 0x00000000u, 0x00000000u},    /* EVX */
182     {0x00000000u, 0x00000000u, 0x00000000u},
183     {0x00000000u, 0x00000000u, 0x00000000u},    /* IVHW */
184     {0x00000000u, 0x00000000u, 0x00000000u},    /* IVTMR */
185     {0xFF00007Fu, 0xFFC00001u, 0x00000000u},    /* IVG7 */
186     {0x00000180u, 0x00000000u, 0x0000003Fu},    /* IVG8 */
187     {0x00001E00u, 0x0000007Eu, 0x00000000u},    /* IVG9 */
188     {0x0000E000u, 0x00001F80u, 0x00000000u},    /* IVG10 */
189     {0x00070000u, 0x0039E000u, 0x3FFFFFC0u},    /* IVG11 */
190     {0x00180000u, 0x00000000u, 0x00000000u},    /* IVG12 */
191     {0x00E00000u, 0x00060000u, 0x00000000u},    /* IVG13 */
192     {0x00000000u, 0x00000000u, 0x00000000u},    /* IVG14 */
193     {0x00000000u, 0x00000000u, 0x00000000u}     /* IVG15 */
194 };
195
196
197 /*
198 * SIC_IARxを解析して、イベント順位ごとに割り当てられている割り込み
199 * のビットマップを作る。SIC_IARxのフィールド値は優先順位-7なので
200 * その分補正する。
201 */
202 #define INSTALL_PRIORITY(imask_idx)    \
203     for ( i=0; i<8; i++ ){ \
204         priority = iar & 0xf;                                       /* IARから優先順位を取り出す */ \
205         priority_mask[priority + 7].imask[imask_idx] |= device;     /* 取り出した優先順位に基づきデバイスを登録 */ \
206         device <<= 1;                                               /* 次のデバイス */ \
207         iar >>= 4;                                                  /* 次のIARフィールド */ \
208     }
209
210 /*
211 *  割り込み順位ごとのISRビットマップの作成SIC_IARxの設定はこの部分より前に済ませること。
212 *  この関数はuITRONのイニシャライザで使用することを想定しており、特に割り込みから保護していない。
213 */
214 void make_priority_mask( void )
215 {
216     unsigned int i, priority, iar;
217     unsigned int device;
218
219         // priority_maskは、event順位0..15に応じた割り込み要求のビットマップを保持する。
220         // 最初にクリアする
221     for ( i=0; i<16; i++ ){
222         priority_mask[i].imask[0] = 0;
223         priority_mask[i].imask[1] = 0;
224         priority_mask[i].imask[2] = 0;
225     }
226
227     device = 1;
228     iar = *pSIC_IAR0;
229     INSTALL_PRIORITY(0)
230
231     iar = *pSIC_IAR1;
232     INSTALL_PRIORITY(0)
233
234     iar = *pSIC_IAR2;
235     INSTALL_PRIORITY(0)
236
237     iar = *pSIC_IAR3;
238     INSTALL_PRIORITY(0)
239
240     device = 1;
241     iar = *pSIC_IAR4;
242     INSTALL_PRIORITY(1)
243
244     iar = *pSIC_IAR5;
245     INSTALL_PRIORITY(1)
246
247     iar = *pSIC_IAR6;
248     INSTALL_PRIORITY(1)
249
250     iar = *pSIC_IAR7;
251     INSTALL_PRIORITY(1)
252
253     device = 1;
254     iar = *pSIC_IAR8;
255     INSTALL_PRIORITY(2)
256
257     iar = *pSIC_IAR9;
258     INSTALL_PRIORITY(2)
259
260     iar = *pSIC_IAR10;
261     INSTALL_PRIORITY(2)
262
263     iar = *pSIC_IAR11;
264     INSTALL_PRIORITY(2)
265 }
266
267
268 /*
269  * 割り込みの許可。ADSP-BF54xは効率的な割り込み処理と安全な割り込み禁止を両立する
270  * 手段を持たないため、禁止関数は置いていない。
271  *
272  * 不便ではあるが、プログラマに注意を促すためにそうしている。
273  */
274 ER ena_int( INTNO intno )
275 {
276     unsigned int mask;
277     SIL_PRE_LOC;
278
279     if ( intno >= DEVICE_INTERRUPT_COUNT )
280         return ( E_PAR );
281     else {
282         if ( intno < 32 ){
283             mask = 1 << intno;
284             SIL_LOC_INT();
285             *pSIC_IMASK0 |= mask;
286             asm volatile( "ssync;" );
287             SIL_UNL_INT();
288         }
289         else if ( intno < 64 ){
290             mask = 1 << (intno-32);
291             SIL_LOC_INT();
292             *pSIC_IMASK1 |= mask;
293             asm volatile( "ssync;" );
294             SIL_UNL_INT();
295         }
296         else {
297             mask = 1 << (intno-64);
298             SIL_LOC_INT();
299             *pSIC_IMASK2 |= mask;
300             asm volatile( "ssync;" );
301             SIL_UNL_INT();
302         }
303         return (0);
304     }
305 }
306
307
308 /*
309  * 割り込みマスクの取得。ADSP-BF54xは効率的な割り込み処理と安全な割り込み禁止を両立する
310  * 手段を持たないため、禁止関数は置いていない。
311  *
312  * 不便ではあるが、プログラマに注意を促すためにそうしている。
313  */
314
315
316 extern ER get_ims( IMS * p_ims )
317 {
318     SIL_PRE_LOC;
319
320     SIL_LOC_INT();
321     p_ims->imask[0] = *pSIC_IMASK0;
322     p_ims->imask[1] = *pSIC_IMASK1;
323     p_ims->imask[2] = *pSIC_IMASK2;
324     SIL_UNL_INT();
325     return( 0 );
326 }
327
328
329 /*
330  *  割り込みをデバイスに割り当てる。
331  *
332  *  この間数は割り込み発生時に共通割り込みハンドラの一部としてアセンブリ言語から割り込み禁止状態で
333  *  呼ばれる。実割り込みハンドラを割り込み可能にするため、asm文を使って途中で割り込み可能にしている。
334  *  割り込み禁止状態で呼ぶのは割り込み源の特定を安全におこなうためである。
335  *
336  */
337 void device_dispatcher( unsigned int priority, unsigned int imask )
338 {
339     unsigned int device;
340     unsigned int candidates[3], sic_isr[3];
341     IMS          sic_imask;
342
343     // 各レジスタの値を取得する。
344     get_ims(&sic_imask);
345     sic_isr[0] = *pSIC_ISR0;
346     sic_isr[1] = *pSIC_ISR1;
347     sic_isr[2] = *pSIC_ISR2;
348
349     // 現在のプライオリティに相当する割込み源を特定する。
350     candidates[0] = priority_mask[priority].imask[0] & sic_isr[0] & sic_imask.imask[0];
351     candidates[1] = priority_mask[priority].imask[1] & sic_isr[1] & sic_imask.imask[1];
352     candidates[2] = priority_mask[priority].imask[2] & sic_isr[2] & sic_imask.imask[2];
353
354     asm volatile("sti %0;": : "d"(imask) );
355
356     // 割り込み源が特定できないなら、コア由来である
357     if ( (0u == candidates[0]) && (0u == candidates[1]) && (0u == candidates[2]) )
358     {
359         if ( priority == ik_hardware_err )
360             dev_vector[INHNO_HW_ERROR]();
361         else
362             if ( priority == ik_timer )
363             dev_vector[INHNO_TIMER]();
364         else
365             dev_vector[INHNO_RAISE]();      // ソフトウェア割り込み
366
367     }
368     else if ((0u != candidates[0]))
369     {
370         if ( candidates[0] & 0x80000000 )
371             device = 31;
372         else
373         {
374 #ifdef __GNUC__
375     asm ( "r1.L = signbits %1; %0 = r1.L(z);":"=d"(device) :"d"(candidates[0]): "R1"  );
376 #elif defined(__ECC__)
377     asm( "%0 = signbits %1;" : "=l"( device ) : "d"( candidates[0] ) );
378 #else
379 #error "Compiler is not supported"
380 #endif
381             device = 30 - device;       // bit mask is converted to bit number
382         }
383         dev_vector[device]();
384     }
385     else if ((0u != candidates[1]))
386     {
387         if ( candidates[1] & 0x80000000 )
388             device = 31;
389         else
390         {
391 #ifdef __GNUC__
392     asm ( "r1.L = signbits %1; %0 = r1.L(z);":"=d"(device) :"d"(candidates[1]): "R1"  );
393 #elif defined(__ECC__)
394     asm( "%0 = signbits %1;" : "=l"( device ) : "d"( candidates[1] ) );
395 #else
396 #error "Compiler is not supported"
397 #endif
398             device = 30 - device;       // bit mask is converted to bit number
399         }
400         dev_vector[device + 32]();
401     }
402     else
403     {
404         if ( candidates[2] & 0x80000000 )
405             device = 31;
406         else
407         {
408 #ifdef __GNUC__
409     asm ( "r1.L = signbits %1; %0 = r1.L(z);":"=d"(device) :"d"(candidates[2]): "R1"  );
410 #elif defined(__ECC__)
411     asm( "%0 = signbits %1;" : "=l"( device ) : "d"( candidates[2] ) );
412 #else
413 #error "Compiler is not supported"
414 #endif
415             device = 30 - device;       // bit mask is converted to bit number
416         }
417         dev_vector[device + 64]();
418     }
419 }
420
421
422
423 /*
424  *  ターゲットシステムの終了。TOPPERS/JSPは対話型ROMモニタに戻ることを想定しているが、
425  *  このボードにROMはない。
426  */
427 void
428 sys_exit()
429 {
430     while(1)
431         ;
432 }
433
434 /*
435  *  ターゲットシステムの文字出力。割り込みが無効な状態でポーリングによる出力を行う。
436  */
437 void
438 sys_putc(char c)
439 {
440     if ( c== 0x0A )         /* もし LF ならば */
441         sys_putc( 0x0D );   /* CRを一文字送信 */
442
443     while( !( *pUART1_LSR & (1<<5)) )
444         ;       /* UART0 LSRのTHREが1になるまで待つ。1ならば送信レジスタ空き。*/
445
446     *pUART1_THR = c;    /* 一文字送信 */
447 }
448
449
450