]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx51/babbage/v2_0/src/board_diag.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / mx51 / babbage / v2_0 / src / board_diag.c
1 /*=============================================================================
2 //
3 //      board_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
42 #include <pkgconf/hal.h>
43
44 #include <cyg/infra/cyg_type.h>         // base types
45 #include <cyg/infra/cyg_trac.h>         // tracing macros
46 #include <cyg/infra/cyg_ass.h>          // assertion macros
47
48 #include <cyg/hal/hal_arch.h>           // basic machine info
49 #include <cyg/hal/hal_intr.h>           // interrupt macros
50 #include <cyg/hal/hal_io.h>             // IO macros
51 #include <cyg/hal/hal_diag.h>
52 #include <cyg/hal/hal_if.h>             // Calling-if API
53 #include <cyg/hal/drv_api.h>            // driver API
54 #include <cyg/hal/hal_misc.h>           // Helper functions
55 #include <cyg/hal/hal_soc.h>            // Hardware definitions
56 #include <cyg/hal/fsl_board.h>          // Platform specifics
57
58 extern void cyg_hal_plf_serial_init(void);
59
60 void cyg_hal_plf_comms_init(void)
61 {
62     static int initialized = 0;
63
64     if (initialized)
65         return;
66
67     initialized = 1;
68
69     /* Setup GPIO and enable transceiver for UARTs */
70     cyg_hal_plf_serial_init();
71 }
72
73 //=============================================================================
74 // Compatibility with older stubs
75 //=============================================================================
76
77 //=============================================================================
78 // Compatibility with older stubs
79 //=============================================================================
80
81 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
82
83 #include <cyg/hal/hal_stub.h>           // cyg_hal_gdb_interrupt
84
85 #if (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 0)
86 #define __BASE   CMA101_DUARTA
87 #define _INT     CYGNUM_HAL_INTERRUPT_SERIAL_A
88 #elif (CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL == 1)
89 #define __BASE   CMA101_DUARTB
90 #define _INT     CYGNUM_HAL_INTERRUPT_SERIAL_B
91 #endif
92
93 #ifdef __BASE
94
95 #ifdef CYGSEM_HAL_ROM_MONITOR
96 #define CYG_HAL_STARTUP_ROM
97 #define CYG_HAL_STARTUP_ROMRAM
98 #undef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
99 #endif
100
101 #if (defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM)) && !defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
102 #define HAL_DIAG_USES_HARDWARE
103 #elif !defined(CYGDBG_HAL_DIAG_TO_DEBUG_CHAN)
104 #define HAL_DIAG_USES_HARDWARE
105 #elif CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL != CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL
106 #define HAL_DIAG_USES_HARDWARE
107 #endif
108
109 static channel_data_t channel = {
110     (uart_width*) _BASE, 0, 0
111 };
112
113 #ifdef HAL_DIAG_USES_HARDWARE
114
115 void hal_diag_init(void)
116 {
117     static int init = 0;
118     char *msg = "\n\rARM eCos\n\r";
119     uart_width lcr;
120
121     if (init++) return;
122
123     init_duart_channel(&channel);
124
125     while (*msg) hal_diag_write_char(*msg++);
126 }
127
128 #ifdef DEBUG_DIAG
129 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
130 #define DIAG_BUFSIZE 32
131 #else
132 #define DIAG_BUFSIZE 2048
133 #endif
134 static char diag_buffer[DIAG_BUFSIZE];
135 static int diag_bp = 0;
136 #endif
137
138 void hal_diag_write_char(char c)
139 {
140     uart_width lsr;
141
142     hal_diag_init();
143
144     cyg_hal_plf_duart_putc(&channel, c)
145
146 #ifdef DEBUG_DIAG
147     diag_buffer[diag_bp++] = c;
148     if (diag_bp == DIAG_BUFSIZE) {
149         while (1) ;
150         diag_bp = 0;
151     }
152 #endif
153 }
154
155 void hal_diag_read_char(char *c)
156 {
157     *c = cyg_hal_plf_duart_getc(&channel);
158 }
159
160 #else // HAL_DIAG relies on GDB
161
162 // Initialize diag port - assume GDB channel is already set up
163 void hal_diag_init(void)
164 {
165     if (0) init_duart_channel(&channel); // avoid warning
166 }
167
168 // Actually send character down the wire
169 static void hal_diag_write_char_serial(char c)
170 {
171     cyg_hal_plf_duart_putc(&channel, c);
172 }
173
174 static bool hal_diag_read_serial(char *c)
175 {
176     long timeout = 1000000000;  // A long time...
177
178     while (!cyg_hal_plf_duart_getc_nonblock(&channel, c))
179         if (0 == --timeout) return false;
180
181     return true;
182 }
183
184 void hal_diag_read_char(char *c)
185 {
186     while (!hal_diag_read_serial(c)) ;
187 }
188
189 void hal_diag_write_char(char c)
190 {
191     static char line[100];
192     static int pos = 0;
193
194     // No need to send CRs
195     if (c == '\r') return;
196
197     line[pos++] = c;
198
199     if (c == '\n' || pos == sizeof(line)) {
200         CYG_INTERRUPT_STATE old;
201
202         // Disable interrupts. This prevents GDB trying to interrupt us
203         // while we are in the middle of sending a packet. The serial
204         // receive interrupt will be seen when we re-enable interrupts
205         // later.
206
207 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
208         CYG_HAL_GDB_ENTER_CRITICAL_IO_REGION(old);
209 #else
210         HAL_DISABLE_INTERRUPTS(old);
211 #endif
212
213         while (1) {
214             static char hex[] = "0123456789ABCDEF";
215             cyg_uint8 csum = 0;
216             int i;
217             char c1;
218
219             hal_diag_write_char_serial('$');
220             hal_diag_write_char_serial('O');
221             csum += 'O';
222             for (i = 0; i < pos; i++) {
223                 char ch = line[i];
224                 char h = hex[(ch>>4)&0xF];
225                 char l = hex[ch&0xF];
226                 hal_diag_write_char_serial(h);
227                 hal_diag_write_char_serial(l);
228                 csum += h;
229                 csum += l;
230             }
231             hal_diag_write_char_serial('#');
232             hal_diag_write_char_serial(hex[(csum>>4)&0xF]);
233             hal_diag_write_char_serial(hex[csum&0xF]);
234
235             // Wait for the ACK character '+' from GDB here and handle
236             // receiving a ^C instead.  This is the reason for this clause
237             // being a loop.
238             if (!hal_diag_read_serial(&c1))
239                 continue;   // No response - try sending packet again
240
241             if ( c1 == '+' )
242                 break;          // a good acknowledge
243
244 #ifdef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT
245             cyg_drv_interrupt_acknowledge(CYG_DEV_SERIAL_INT);
246             if ( c1 == 3 ) {
247                 // Ctrl-C: breakpoint.
248                 cyg_hal_gdb_interrupt (__builtin_return_address(0));
249                 break;
250             }
251 #endif
252             // otherwise, loop round again
253         }
254
255         pos = 0;
256
257         // And re-enable interrupts
258 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
259         CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION(old);
260 #else
261         HAL_RESTORE_INTERRUPTS(old);
262 #endif
263
264     }
265 }
266 #endif
267
268 #endif // __BASE
269
270 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_DIAG
271
272 /*---------------------------------------------------------------------------*/