]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/powerpc/mbx/v2_0/src/hal_diag.c
Initial revision
[karo-tx-redboot.git] / packages / hal / powerpc / mbx / 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):   hmt
44 // Contributors:hmt, jskov
45 // Date:        1999-06-08
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_io.h>             // IO macros
60 #include <cyg/hal/hal_diag.h>
61 #include <cyg/hal/hal_intr.h>           // Interrupt macros
62
63 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
64 #include <cyg/hal/hal_stub.h>           // hal_output_gdb_string
65 #endif
66
67 #include <cyg/hal/ppc_regs.h>
68 #include <cyg/hal/quicc/quicc_smc1.h>
69
70
71 void
72 cyg_hal_plf_comms_init(void)
73 {
74     static int initialized = 0;
75
76     if (initialized)
77         return;
78     initialized = 1;
79
80     cyg_hal_plf_serial_init();
81 }
82
83
84 #if !defined(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG)
85
86 //-----------------------------------------------------------------------------
87 // Select default diag channel to use
88
89 //#define CYG_KERNEL_DIAG_ROMART
90 //#define CYG_KERNEL_DIAG_SERIAL
91
92 #if !defined(CYG_KERNEL_DIAG_SERIAL)
93 #define CYG_KERNEL_DIAG_SERIAL
94 #endif
95
96 #ifdef CYGDBG_DIAG_BUF
97 // Keep diag messages in a buffer for later [re]display
98
99 int enable_diag_uart = 1;
100 int enable_diag_buf = 1;
101 static char diag_buf[40960*4];
102 static int  diag_buf_ptr = 0;
103
104 static void
105 diag_putc(char c)
106 {
107     if (enable_diag_buf) {
108         diag_buf[diag_buf_ptr++] = c;
109         if (diag_buf_ptr == sizeof(diag_buf)) diag_buf_ptr--;
110     }
111 }
112
113 void
114 dump_diag_buf(int start, int len)
115 {
116     int i;
117     enable_diag_uart = 1;
118     enable_diag_buf = 0;
119     if (len == 0) len = diag_buf_ptr;
120     diag_printf("\nDiag buf\n");
121     for (i = start;  i < len;  i++) {
122         hal_diag_write_char(diag_buf[i]);
123     }
124 }
125 #endif // CYGDBG_DIAG_BUF
126
127
128 //-----------------------------------------------------------------------------
129 // MBX board specific serial output; using GDB protocol by default:
130
131
132 #if defined(CYG_KERNEL_DIAG_SERIAL)
133
134 EPPC *eppc;
135
136 void hal_diag_init(void)
137 {
138     static int init = 0;
139     if (init) return;
140     init++;
141
142     // hardwired base
143     eppc = eppc_base();
144
145     // init the actual serial port
146     cyg_hal_plf_serial_init_channel();
147 #ifdef CYGSEM_HAL_DIAG_MANGLER_GDB
148 #ifndef CYG_HAL_STARTUP_ROM
149     // We are talking to GDB; ack the "go" packet!
150     cyg_hal_plf_serial_putc(eppc, '+');
151 #endif
152 #endif
153 }
154
155 void hal_diag_write_char_serial( char c )
156 {
157     unsigned long __state;
158     HAL_DISABLE_INTERRUPTS(__state);
159     cyg_hal_plf_serial_putc(eppc, c);
160     HAL_RESTORE_INTERRUPTS(__state);
161 }
162
163 #if defined(CYG_HAL_STARTUP_ROM) || !defined(CYGDBG_HAL_DIAG_TO_DEBUG_CHAN)
164 void hal_diag_write_char(char c)
165 {
166 #ifdef CYGDBG_DIAG_BUF
167     diag_putc(c);
168     if (!enable_diag_uart) return;
169 #endif // CYGDBG_DIAG_BUF
170     hal_diag_write_char_serial(c);
171 }
172
173 #else // RAM start so encode for GDB
174
175 void hal_diag_write_char(char c)
176 {
177     static char line[100];
178     static int pos = 0;
179
180 #ifdef CYGDBG_DIAG_BUF
181     diag_putc(c);
182     if (!enable_diag_uart) return;
183 #endif // CYGDBG_DIAG_BUF
184
185     // No need to send CRs
186     if( c == '\r' ) return;
187
188     line[pos++] = c;
189
190     if( c == '\n' || pos == sizeof(line) )
191     {
192         CYG_INTERRUPT_STATE old;
193
194         // Disable interrupts. This prevents GDB trying to interrupt us
195         // while we are in the middle of sending a packet. The serial
196         // receive interrupt will be seen when we re-enable interrupts
197         // later.
198         
199 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
200         CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
201 #else
202         HAL_DISABLE_INTERRUPTS(old);
203 #endif
204         
205         while(1)
206         {
207             static char hex[] = "0123456789ABCDEF";
208             cyg_uint8 csum = 0;
209             int i;
210         
211             hal_diag_write_char_serial('$');
212             hal_diag_write_char_serial('O');
213             csum += 'O';
214             for( i = 0; i < pos; i++ )
215             {
216                 char ch = line[i];
217                 char h = hex[(ch>>4)&0xF];
218                 char l = hex[ch&0xF];
219                 hal_diag_write_char_serial(h);
220                 hal_diag_write_char_serial(l);
221                 csum += h;
222                 csum += l;
223             }
224             hal_diag_write_char_serial('#');
225             hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
226             hal_diag_write_char_serial(hex[csum&0xF]);
227
228 #ifndef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
229             // only gobble characters if no interrupt handler to grab ^Cs
230             // is installed (which is exclusive with device driver use)
231
232             // Wait for the ACK character '+' from GDB here and handle
233             // receiving a ^C instead.  This is the reason for this clause
234             // being a loop.
235             c = cyg_hal_plf_serial_getc(eppc);
236
237             if( c == '+' )
238                 break;              // a good acknowledge
239 #if 0
240             if( c1 == 3 ) {
241                 // Ctrl-C: breakpoint.
242                 breakpoint();
243                 break;
244             }
245 #endif
246             // otherwise, loop round again
247 #else
248             break;
249 #endif
250         }
251         
252         pos = 0;
253
254         // And re-enable interrupts
255 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
256         CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
257 #else
258         HAL_RESTORE_INTERRUPTS(old);
259 #endif
260         
261     }
262 }
263 #endif // NOT def CYG_HAL_STARTUP_ROM
264
265
266 void hal_diag_read_char(char *c)
267 {
268     *c = cyg_hal_plf_serial_getc(eppc);
269 }
270
271 #endif // CYG_KERNEL_DIAG_SERIAL
272
273 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
274
275 // EOF hal_diag.c