]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/fr30/mb91301/v2_0/src/hal_diag.c
Initial revision
[karo-tx-redboot.git] / packages / hal / fr30 / mb91301 / v2_0 / src / hal_diag.c
1 /*=============================================================================
2 //
3 //      hal_diag.c
4 //
5 //      HAL diagnostic output code
6 //
7 //=============================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //=============================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):   larsi
44 // Contributors:larsi
45 // Date:        2006-07-26
46 // Purpose:     HAL diagnostic output
47 // Description: Implementations of HAL diagnostic output support.
48 //
49 //####DESCRIPTIONEND####
50 //
51 //===========================================================================*/
52
53 #include <pkgconf/hal.h>
54
55 #include <cyg/infra/cyg_type.h>         // base types
56 #include <cyg/infra/cyg_trac.h>         // tracing macros
57 #include <cyg/infra/cyg_ass.h>          // assertion macros
58
59 #include <cyg/hal/hal_arch.h>
60 #include <cyg/hal/hal_diag.h>
61
62 #include <cyg/hal/hal_intr.h>
63
64 #include <cyg/hal/hal_io.h>
65
66 #include <cyg/hal/hal_misc.h>
67 /*---------------------------------------------------------------------------*/
68
69 //#define CYG_KERNEL_DIAG_LCD
70 #define CYG_KERNEL_DIAG_SERIAL0 // For ROM start but see immediately below:
71
72 #if defined(CYGSEM_HAL_USE_ROM_MONITOR_CygMon)
73 #undef CYG_KERNEL_DIAG_SERIAL0
74 #undef CYG_KERNEL_DIAG_LCD
75 #define CYG_KERNEL_DIAG_CYGMON
76 #define CYG_KERNEL_DIAG_GDB
77
78 #endif
79
80 /*---------------------------------------------------------------------------*/
81
82 #if defined(CYG_KERNEL_DIAG_SERIAL0) || defined(CYG_KERNEL_DIAG_CYGMON)
83
84 /*---------------------------------------------------------------------------*/
85 // LED diag function
86 /*
87 void hal_diag_init_led(){
88 // we only init the first 4 leds here
89         asm volatile(
90         "ldi:8  #0xf,   r4;\n"
91         "ldi:20 #CYG_HAL_FR30_MB91360_DDRJ,     r5;\n"
92         "stb    r4,     @r5;\n"
93         "ldi:20 #CYG_HAL_FR30_MB91360_PFRJ, r5;\n"
94         "stb    r4,     @r5;\n"
95         : : :"r4", "r5"
96     );
97 }
98 */
99 // static cyg_uint8 leds = 0;
100
101 void hal_diag_init(void){
102
103     // PJ2(SCK0) & PJ1(SOT0) output, PJ0(SIN0) input
104     HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_DDRJ, 0x6);
105     // PJ2(SCK0) & PJ1(SOT0) & PJ0(SIN0) to peripheral operation
106     HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PFRJ, 0x7);
107
108     // set up U-Timer
109     HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_UTIMC0, 0x02);
110     // 115200 bps
111     HAL_WRITE_UINT16(CYG_HAL_FR30_MB91301_UTIMR0, 0x7);
112
113     // setup UART
114     HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_SCR0, 0x13);
115     HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_SMR0, 0x30);
116 }
117
118
119 void hal_diag_led(cyg_uint8 leds)
120 {
121
122     HAL_WRITE_UINT8(CYG_HAL_FR30_MB91301_PDRG, leds);
123
124 }
125
126 /*---------------------------------------------------------------------------*/
127
128 void hal_diag_write_char_serial0( char c)
129 {
130     cyg_uint8 ssr;
131
132     do
133     {
134         HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
135     } while (!(ssr & BIT3));
136
137     HAL_WRITE_UINT8( CYG_HAL_FR30_MB91301_SODR0, c );
138
139 }
140
141 void hal_diag_write_hex_serial0(unsigned int c)
142 {
143     unsigned char chr;
144     int i;
145
146     hal_diag_write_char_serial0('0');
147     hal_diag_write_char_serial0('x');
148
149     for(i = 28; i >= 0; i = i - 4)
150     {
151         chr = (c >> i) & 0xf;
152         if (chr >= 10) chr = chr + 55;   /* for A-F */
153         else  chr = chr + 48;  /* for 0-9 */
154         hal_diag_write_char_serial0(chr);
155     }
156     hal_diag_write_char_serial0('\n');
157     hal_diag_write_char_serial0('\r');
158 }
159
160
161 void hal_diag_drain(void)
162 {
163     cyg_uint8 ssr;
164
165         do
166     {
167         HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
168     } while (!(ssr & BIT3));
169 }
170
171 void hal_diag_read_char_serial0(char *c)
172 {
173     cyg_uint8 ssr;
174
175     do
176     {
177         HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SSR0 , ssr );
178     } while (!(ssr & BIT4));
179
180     HAL_READ_UINT8( CYG_HAL_FR30_MB91301_SIDR0, *c );
181
182 }
183
184
185 #if defined(CYG_KERNEL_DIAG_CYGMON)
186 void hal_diag_dumb_write_char(char c)
187 #else
188 void hal_diag_write_char(char c)
189 #endif
190 {
191 #ifdef CYG_KERNEL_DIAG_GDB
192     static char line[100];
193     static int pos = 0;
194 //    register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR;    
195
196     // No need to send CRs
197     if( c == '\r' ) return;
198
199     line[pos++] = c;
200
201     if( c == '\n' || pos == sizeof(line) )
202     {
203
204         // Disable interrupts. This prevents GDB trying to interrupt us
205         // while we are in the middle of sending a packet. The serial
206         // receive interrupt will be seen when we re-enable interrupts
207         // later.
208         CYG_INTERRUPT_STATE oldstate;
209         HAL_DISABLE_INTERRUPTS(oldstate);
210         
211         while(1)
212         {
213             static char hex[] = "0123456789ABCDEF";
214             cyg_uint8 csum = 0;
215             int i;
216             char c1;
217         
218             hal_diag_write_char_serial0('$');
219             hal_diag_write_char_serial0('O');
220             csum += 'O';
221             for( i = 0; i < pos; i++ )
222             {
223                 char ch = line[i];
224                 char h = hex[(ch>>4)&0xF];
225                 char l = hex[ch&0xF];
226                 hal_diag_write_char_serial0(h);
227                 hal_diag_write_char_serial0(l);
228                 csum += h;
229                 csum += l;
230             }
231             hal_diag_write_char_serial0('#');
232             hal_diag_write_char_serial0(hex[(csum>>4)&0xF]);
233             hal_diag_write_char_serial0(hex[csum&0xF]);
234
235             hal_diag_read_char_serial0( &c1 );
236
237             if( c1 == '+' ) break;
238
239             {
240                 extern void cyg_hal_user_break(CYG_ADDRWORD *regs);
241                 extern cyg_bool cyg_hal_is_break(char *buf, int size);
242                 if( cyg_hal_is_break( &c1 , 1 ) )
243                     cyg_hal_user_break( NULL );    
244             }
245             
246             break;
247         }
248         
249         pos = 0;
250
251         // Wait for all data from serial line to drain
252         // and clear ready-to-send indication.
253         hal_diag_drain_serial0();
254         
255         // And re-enable interrupts
256         HAL_RESTORE_INTERRUPTS( oldstate );
257         
258     }
259 #else
260     hal_diag_write_char_serial0(c);
261 #endif    
262 }
263
264
265 void hal_diag_read_char(char *c)
266 {
267     for(;;)
268     {
269 #if defined(CYG_KERNEL_DIAG_GDB) && defined(CYGSEM_HAL_USE_ROM_MONITOR)
270
271         typedef void rom_read_fn(char *c);
272         rom_read_fn *fn = ((rom_read_fn **)0x80000100)[62];
273
274         fn(c);
275     
276 #else    
277         hal_diag_read_char_serial0(c);
278
279 #endif    
280
281 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
282         if( *c == 3 )
283         {
284             // Ctrl-C: breakpoint.
285             extern void breakpoint(void);
286             breakpoint();
287             continue;
288         }
289 #elif defined(CYGSEM_HAL_USE_ROM_MONITOR)
290         if( *c == 3 )
291         {
292             // Ctrl-C: breakpoint.
293
294 //                HAL_BREAKPOINT(_breakinst);
295             typedef void bpt_fn(void);
296             bpt_fn *bfn = ((bpt_fn **)0x80000100)[61];
297
298             bfn();
299             continue;            
300         }
301 #endif
302
303         break;      
304     }
305 }
306
307 #endif // defined(CYG_KERNEL_DIAG_SERIAL0) || defined(CYG_KERNEL_DIAG_CYGMON)
308
309
310 #if defined(CYG_KERNEL_DIAG_CYGMON) // only
311
312 /* This code has been imported from the BSP module. The definitions have
313  * been left as-is, even though there was scope for doing more, to avoid
314  * too much drift from the original sources
315  */
316
317 struct bsp_comm_procs {
318     void *ch_data;
319     void (*__write)(void *ch_data, const char *buf, int len);
320     int  (*__read)(void *ch_data, char *buf, int len);
321     void (*__putc)(void *ch_data, char ch);
322     int  (*__getc)(void *ch_data);
323     int  (*__control)(void *ch_data, int func, ...);
324 };
325
326 // This is pointed to by entry BSP_NOTVEC_BSP_COMM_PROCS:
327 typedef struct {
328     int  version;       /* version number for future expansion */
329     void *__ictrl_table;
330     void *__exc_table;
331     void *__dbg_vector;
332     void *__kill_vector;
333     struct bsp_comm_procs *__console_procs;
334     struct bsp_comm_procs *__debug_procs;
335     void *__flush_dcache;
336     void *__flush_icache;
337     void *__cpu_data;
338     void *__board_data;
339     void *__sysinfo;
340     int  (*__set_debug_comm)(int __comm_id);
341     int  (*__set_console_comm)(int __comm_id);
342     int  (*__set_serial_baud)(int __comm_id, int baud);
343     void *__dbg_data;
344     void (*__reset)(void);
345     int  __console_interrupt_flag;
346 } bsp_shared_t;
347
348 /*
349  * Core Exception vectors.
350  */
351 #define BSP_EXC_INT         0
352 #define BSP_EXC_TLBMOD      1
353 #define BSP_EXC_TLBL        2
354 #define BSP_EXC_TLBS        3
355 #define BSP_EXC_ADEL        4
356 #define BSP_EXC_ADES        5
357 #define BSP_EXC_IBE         6
358 #define BSP_EXC_DBE         7
359 #define BSP_EXC_SYSCALL     8
360 #define BSP_EXC_BREAK       9
361 #define BSP_EXC_ILL        10
362 #define BSP_EXC_CPU        11
363 #define BSP_EXC_OV         12
364 #define BSP_EXC_TRAP       13
365 #define BSP_EXC_VCEI       14
366 #define BSP_EXC_FPE        15
367 #define BSP_EXC_RSV16      16
368 #define BSP_EXC_RSV17      17
369 #define BSP_EXC_RSV18      18
370 #define BSP_EXC_RSV19      19
371 #define BSP_EXC_RSV20      20
372 #define BSP_EXC_RSV21      21
373 #define BSP_EXC_RSV22      22
374 #define BSP_EXC_WATCH      23
375 #define BSP_EXC_RSV24      24
376 #define BSP_EXC_RSV25      25
377 #define BSP_EXC_RSV26      26
378 #define BSP_EXC_RSV27      27
379 #define BSP_EXC_RSV28      28
380 #define BSP_EXC_RSV29      29
381 #define BSP_EXC_RSV30      30
382 #define BSP_EXC_VCED       31
383 /* tx39 debug exception */
384 #define BSP_EXC_DEBUG      32
385 #define BSP_EXC_TLB        33
386 #define BSP_EXC_NMI        34
387 /*
388  * Hack for eCos on tx39 to set an async breakpoint.
389  */
390 #define BSP_VEC_BP_HOOK    35
391
392 #define BSP_EXC_XTLB       36
393 #define BSP_EXC_CACHE      37
394
395 #define BSP_MAX_EXCEPTIONS 38
396
397 /*
398  * Another hack for tx39 eCos compatibility.
399  */
400 #if defined(__CPU_R3900__)
401 #define BSP_VEC_MT_DEBUG   15
402 #else
403 #define BSP_VEC_MT_DEBUG   38
404 #endif
405
406 #define BSP_VEC_STUB_ENTRY 39
407 #define BSP_VEC_BSPDATA    40
408 #define BSP_VEC_MAGIC      41
409 #define BSP_VEC_IRQ_CHECK  42
410
411 #define BSP_VEC_PAD        43
412 #define NUM_VTAB_ENTRIES   44
413
414
415 #define BSP_MAGIC_VAL      0x55aa4321
416
417 #define SYS_interrupt 1000
418
419 // These vectors should be called with:
420 //
421 //  k0 - Exception Number
422
423 #define CYGMON_VECTOR_TABLE_BASE 0x80000100
424 #define CYGMON_VECTOR_TABLE ((CYG_ADDRESS *)CYGMON_VECTOR_TABLE_BASE)
425
426 #if 0 // UNUSED
427 static int
428 hal_bsp_set_debug_comm(int arg)
429 {
430     bsp_shared_t *shared;
431
432     shared = (bsp_shared_t *)
433         (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
434
435     if (0 != shared->__set_debug_comm) {
436         return (*(shared->__set_debug_comm))(arg);
437     }
438     return 0;
439 }
440
441 static int
442 hal_bsp_set_console_comm(int arg)
443 {
444     bsp_shared_t *shared;
445
446     shared = (bsp_shared_t *)
447         (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
448
449     if (0 != shared->__set_console_comm) {
450         return (*(shared->__set_console_comm))(arg);
451     }
452     return 0;
453 }
454 #endif // 0 UNUSED
455
456 static void bsp_trap(int trap_num);
457
458 static int
459 hal_bsp_console_write(const void *p, int len)
460 {
461     bsp_shared_t *shared;
462     struct bsp_comm_procs *com;
463     int  magic;
464
465     /*hal_bsp_set_console_comm(0);*/
466
467     /* If this is not a BSP-based CygMon, return 0 */
468     magic = (int)(CYGMON_VECTOR_TABLE[ BSP_VEC_MAGIC ]);
469     if (magic != BSP_MAGIC_VAL)
470         return 0;
471
472     shared = (bsp_shared_t *)
473         (CYGMON_VECTOR_TABLE[ BSP_VEC_BSPDATA ]);
474
475     com = shared->__console_procs;
476
477     if (0 != com) {
478         shared->__console_interrupt_flag = 0;
479         com->__write(com->ch_data, p, len);
480         if (shared->__console_interrupt_flag) {
481             /* debug interrupt; stop here */
482             bsp_trap(SYS_interrupt);
483         }
484
485         return 1;
486     }
487     return 0;
488 }
489
490 static void
491 bsp_trap(int trap_num)
492 {
493     asm("syscall\n");
494 }
495
496
497 static void
498 hal_dumb_serial_write(const char *p, int len)
499 {
500     int i;
501     for ( i = 0 ; i < len; i++ ) {
502         hal_diag_dumb_write_char(p[i]);
503     }
504
505 /*
506 void hal_diag_write_char(char c)
507 {
508     static char line[100];
509     static int pos = 0;
510
511     // No need to send CRs
512     if( c == '\r' ) return;
513
514     line[pos++] = c;
515
516     if( c == '\n' || pos == sizeof(line) ) {
517         CYG_INTERRUPT_STATE old;
518
519         // Disable interrupts. This prevents GDB trying to interrupt us
520         // while we are in the middle of sending a packet. The serial
521         // receive interrupt will be seen when we re-enable interrupts
522         // later.
523         
524         HAL_DISABLE_INTERRUPTS(old);
525         
526         if ( ! hal_bsp_console_write( line, pos ) )
527             // then there is no function registered, just spew it out serial
528             hal_dumb_serial_write( line, pos );
529         
530         pos = 0;
531
532         // And re-enable interrupts
533         HAL_RESTORE_INTERRUPTS(old);
534
535     }
536 }*/
537
538 int
539 hal_diag_irq_check(int vector)
540 {
541     typedef int irq_check_fn(int irq_nr);
542     irq_check_fn *fn = (irq_check_fn *)(CYGMON_VECTOR_TABLE[ BSP_VEC_IRQ_CHECK ]);
543     int  magic;
544     
545
546     /* If this is not a BSP-based CygMon, return 0 */
547     magic = (int)(CYGMON_VECTOR_TABLE[ BSP_VEC_MAGIC ]);
548     if (magic != BSP_MAGIC_VAL)
549         return 0;
550
551 #if defined(CYGPKG_HAL_MIPS_TX3904)
552     /* convert vector to BSP irq number */
553     if (vector == 16)
554         vector = 2;
555     else
556         vector += 3;
557 #endif
558
559     return fn(vector);
560 }
561
562 #endif // defined(CYG_KERNEL_DIAG_CYGMON) *only*
563
564
565 /*---------------------------------------------------------------------------*/
566 /* End of hal_diag.c */