|
0
|
1 /*============================================================================= |
|
|
2 // |
|
|
3 // hal_diag.c |
|
|
4 // |
|
|
5 // HAL diagnostic output code |
|
|
6 // |
|
|
7 //============================================================================= |
|
|
8 //####COPYRIGHTBEGIN#### |
|
|
9 // |
|
|
10 // ------------------------------------------- |
|
|
11 // The contents of this file are subject to the Cygnus eCos Public License |
|
|
12 // Version 1.0 (the "License"); you may not use this file except in |
|
|
13 // compliance with the License. You may obtain a copy of the License at |
|
|
14 // http://sourceware.cygnus.com/ecos |
|
|
15 // |
|
|
16 // Software distributed under the License is distributed on an "AS IS" |
|
|
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the |
|
|
18 // License for the specific language governing rights and limitations under |
|
|
19 // the License. |
|
|
20 // |
|
|
21 // The Original Code is eCos - Embedded Cygnus Operating System, released |
|
|
22 // September 30, 1998. |
|
|
23 // |
|
|
24 // The Initial Developer of the Original Code is Cygnus. Portions created |
|
|
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. |
|
|
26 // ------------------------------------------- |
|
|
27 // |
|
|
28 //####COPYRIGHTEND#### |
|
|
29 //============================================================================= |
|
|
30 //#####DESCRIPTIONBEGIN#### |
|
|
31 // |
|
|
32 // Author(s): nickg |
|
|
33 // Contributors: nickg |
|
|
34 // Date: 1998-03-02 |
|
|
35 // Purpose: HAL diagnostic output |
|
|
36 // Description: Implementations of HAL diagnostic output support. |
|
|
37 // |
|
|
38 //####DESCRIPTIONEND#### |
|
|
39 // |
|
|
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_diag.h> |
|
|
49 #include <cyg/hal/hal_intr.h> |
|
|
50 |
|
|
51 /*---------------------------------------------------------------------------*/ |
|
|
52 /* Select default diag channel to use */ |
|
|
53 |
|
|
54 //#define CYG_KERNEL_DIAG_ROMART |
|
|
55 //#define CYG_KERNEL_DIAG_SERIAL1 |
|
|
56 //#define CYG_KERNEL_DIAG_SERIAL2 |
|
|
57 //#define CYG_KERNEL_DIAG_GDB |
|
|
58 |
|
|
59 #if !defined(CYG_KERNEL_DIAG_SERIAL1) && \ |
|
|
60 !defined(CYG_KERNEL_DIAG_SERIAL2) && \ |
|
|
61 !defined(CYG_KERNEL_DIAG_ROMART) |
|
|
62 |
|
|
63 # if defined(CYG_HAL_MN10300_STDEVAL1) |
|
|
64 |
|
|
65 # if defined(CYG_HAL_STARTUP_RAM) |
|
|
66 |
|
|
67 # if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) |
|
|
68 |
|
|
69 // If loaded into RAM via CYGMON we diag via |
|
|
70 // serial 2 using GDB protocol |
|
|
71 |
|
|
72 # define CYG_KERNEL_DIAG_SERIAL2 |
|
|
73 # define CYG_KERNEL_DIAG_GDB |
|
|
74 |
|
|
75 # elif defined(CYG_HAL_USE_ROM_MONITOR_SLOAD) |
|
|
76 |
|
|
77 // If loaded into RAM via SLOAD we diag via |
|
|
78 // serial 1 |
|
|
79 |
|
|
80 # define CYG_KERNEL_DIAG_SERIAL1 |
|
|
81 |
|
|
82 # elif defined(CYG_HAL_USE_ROM_MONITOR_GDB_STUBS) |
|
|
83 |
|
|
84 // If loaded into RAM via GDB STUB ROM we diag via |
|
|
85 // serial 1 using GDB protocol |
|
|
86 |
|
|
87 # define CYG_KERNEL_DIAG_SERIAL1 |
|
|
88 # define CYG_KERNEL_DIAG_GDB |
|
|
89 |
|
|
90 # endif // defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) |
|
|
91 |
|
|
92 # elif defined(CYG_HAL_STARTUP_ROM) |
|
|
93 |
|
|
94 // If we are ROM resident, we diag via serial 1 |
|
|
95 |
|
|
96 # define CYG_KERNEL_DIAG_SERIAL1 |
|
|
97 |
|
|
98 # endif // defined(CYG_HAL_STARTUP_RAM) |
|
|
99 |
|
|
100 # endif // defined(CYG_HAL_MN10300_STDEVAL1) |
|
|
101 |
|
|
102 #endif // if ... |
|
|
103 |
|
|
104 /*---------------------------------------------------------------------------*/ |
|
|
105 // PromICE AI interface |
|
|
106 |
|
|
107 #if defined(CYG_HAL_MN10300_STDEVAL1_ROMART) || defined(CYG_KERNEL_DIAG_ROMART) |
|
|
108 |
|
|
109 #ifdef CYG_HAL_MN10300_STDEVAL1 |
|
|
110 #define PROMICE_AILOC 0x40008000 |
|
|
111 #endif |
|
|
112 |
|
|
113 #define PROMICE_BUS_SIZE 16 |
|
|
114 #define PROMICE_BURST_SIZE 1 |
|
|
115 |
|
|
116 #if PROMICE_BUS_SIZE == 16 |
|
|
117 |
|
|
118 typedef volatile struct |
|
|
119 { |
|
|
120 volatile cyg_uint16 zero; |
|
|
121 // cyg_uint16 pad1[PROMICE_BURST_SIZE]; |
|
|
122 volatile cyg_uint16 one; |
|
|
123 // cyg_uint16 pad2[PROMICE_BURST_SIZE]; |
|
|
124 volatile cyg_uint16 data; |
|
|
125 // cyg_uint16 pad3[PROMICE_BURST_SIZE]; |
|
|
126 volatile cyg_uint16 status; |
|
|
127 |
|
|
128 } AISTRUCT; |
|
|
129 |
|
|
130 #endif |
|
|
131 |
|
|
132 AISTRUCT *AI = (AISTRUCT *)PROMICE_AILOC; |
|
|
133 |
|
|
134 #define PROMICE_STATUS_TDA 0x01 |
|
|
135 #define PROMICE_STATUS_HDA 0x02 |
|
|
136 #define PROMICE_STATUS_OVR 0x04 |
|
|
137 |
|
|
138 |
|
|
139 void ai_diag_init() |
|
|
140 { |
|
|
141 volatile cyg_uint8 junk; |
|
|
142 |
|
|
143 while( AI->status == 0xCC ) |
|
|
144 continue; |
|
|
145 |
|
|
146 junk = AI->data; |
|
|
147 } |
|
|
148 |
|
|
149 static void ai_write_char(cyg_uint8 data) |
|
|
150 { |
|
|
151 volatile cyg_uint8 junk; |
|
|
152 int i; |
|
|
153 |
|
|
154 // Wait for tda == 0 |
|
|
155 while( (AI->status & PROMICE_STATUS_TDA) == PROMICE_STATUS_TDA ) |
|
|
156 continue; |
|
|
157 |
|
|
158 // Send start bit |
|
|
159 junk = AI->one; |
|
|
160 |
|
|
161 for( i = 0; i < 8; i++ ) |
|
|
162 { |
|
|
163 // send ls bit of data |
|
|
164 if( (data & 1) == 1 ) |
|
|
165 junk = AI->one; |
|
|
166 else |
|
|
167 junk = AI->zero; |
|
|
168 |
|
|
169 // shift down for next bit |
|
|
170 data >>= 1; |
|
|
171 } |
|
|
172 |
|
|
173 // Send stop bit |
|
|
174 junk = AI->one; |
|
|
175 |
|
|
176 // all done |
|
|
177 } |
|
|
178 |
|
|
179 void ai_diag_write_char(char c) |
|
|
180 { |
|
|
181 ai_write_char((cyg_uint8)c); |
|
|
182 } |
|
|
183 |
|
|
184 void ai_diag_drain() {} |
|
|
185 |
|
|
186 void ai_diag_read_char(char *c) { *c = '\n'; } |
|
|
187 |
|
|
188 void ai_writes(char *s) |
|
|
189 { |
|
|
190 while( *s ) ai_write_char( *s++ ); |
|
|
191 } |
|
|
192 |
|
|
193 void ai_write_hex( cyg_uint32 x) |
|
|
194 { |
|
|
195 int i; |
|
|
196 ai_writes("0x"); |
|
|
197 for( i = 28; i >=0 ; i-=4 ) |
|
|
198 { |
|
|
199 char *d = "0123456789ABCDEF"; |
|
|
200 ai_write_char( d[(x>>i)&0xf] ); |
|
|
201 } |
|
|
202 ai_write_char(' '); |
|
|
203 } |
|
|
204 |
|
|
205 #if defined(CYG_KERNEL_DIAG_ROMART) |
|
|
206 |
|
|
207 #define hal_diag_init_serial ai_diag_init |
|
|
208 #define hal_diag_write_char_serial ai_diag_write_char |
|
|
209 #define hal_diag_drain_serial ai_diag_drain |
|
|
210 #define hal_diag_read_char_serial ai_diag_read_char |
|
|
211 |
|
|
212 #endif |
|
|
213 |
|
|
214 #endif |
|
|
215 |
|
|
216 /*---------------------------------------------------------------------------*/ |
|
|
217 // MN10300 Serial line |
|
|
218 |
|
|
219 #if defined(CYG_HAL_MN10300_STDEVAL1_SERIAL1) || defined(CYG_KERNEL_DIAG_SERIAL1) |
|
|
220 |
|
|
221 // We use serial1 on MN103002 |
|
|
222 #define SERIAL1_CR ((volatile cyg_uint16 *)0x34000810) |
|
|
223 #define SERIAL1_ICR ((volatile cyg_uint8 *) 0x34000814) |
|
|
224 #define SERIAL1_TXR ((volatile cyg_uint8 *) 0x34000818) |
|
|
225 #define SERIAL1_RXR ((volatile cyg_uint8 *) 0x34000819) |
|
|
226 #define SERIAL1_SR ((volatile cyg_uint16 *)0x3400081c) |
|
|
227 |
|
|
228 // Timer 1 provided baud rate divisor |
|
|
229 #define TIMER1_MD ((volatile cyg_uint8 *)0x34001001) |
|
|
230 #define TIMER1_BR ((volatile cyg_uint8 *)0x34001011) |
|
|
231 #define TIMER1_CR ((volatile cyg_uint8 *)0x34001021) |
|
|
232 |
|
|
233 #define PORT3_MD ((volatile cyg_uint8 *)0x36008025) |
|
|
234 |
|
|
235 // Mystery register |
|
|
236 #define TMPSCNT ((volatile cyg_uint8 *)0x34001071) |
|
|
237 |
|
|
238 #define SIO1_LSTAT_TRDY 0x20 |
|
|
239 #define SIO1_LSTAT_RRDY 0x10 |
|
|
240 |
|
|
241 void hal_diag_init_serial1(void) |
|
|
242 { |
|
|
243 // 48 translates to 38400 baud. |
|
|
244 *TIMER1_BR = 48; |
|
|
245 |
|
|
246 // Timer1 sourced from IOCLK |
|
|
247 *TIMER1_MD = 0x80; |
|
|
248 |
|
|
249 // Mode on PORT3, used for serial line controls. |
|
|
250 *PORT3_MD = 0x01; |
|
|
251 |
|
|
252 // No interrupts for now. |
|
|
253 *SERIAL1_ICR = 0x00; |
|
|
254 |
|
|
255 // Source from timer 1, 8bit chars, enable tx and rx |
|
|
256 *SERIAL1_CR = 0xc084; |
|
|
257 } |
|
|
258 |
|
|
259 void hal_diag_write_char_serial1(char c) |
|
|
260 { |
|
|
261 register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR; |
|
|
262 register volatile cyg_uint8 *volatile tty_tx = SERIAL1_TXR; |
|
|
263 |
|
|
264 while( (*tty_status & SIO1_LSTAT_TRDY) != 0 ) continue; |
|
|
265 |
|
|
266 *tty_tx = c; |
|
|
267 } |
|
|
268 |
|
|
269 void hal_diag_drain_serial1(void) |
|
|
270 { |
|
|
271 register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR; |
|
|
272 |
|
|
273 while( (*tty_status & SIO1_LSTAT_TRDY) != 0 ) continue; |
|
|
274 } |
|
|
275 |
|
|
276 void hal_diag_read_char_serial1(char *c) |
|
|
277 { |
|
|
278 register volatile cyg_uint16 *volatile tty_status = SERIAL1_SR; |
|
|
279 register volatile cyg_uint8 *volatile tty_rx = SERIAL1_RXR; |
|
|
280 |
|
|
281 while( (*tty_status & SIO1_LSTAT_RRDY) == 0 ) continue; |
|
|
282 |
|
|
283 *c = *tty_rx; |
|
|
284 |
|
|
285 } |
|
|
286 |
|
|
287 #if defined(CYG_KERNEL_DIAG_SERIAL1) |
|
|
288 |
|
|
289 #define hal_diag_init_serial hal_diag_init_serial1 |
|
|
290 #define hal_diag_write_char_serial hal_diag_write_char_serial1 |
|
|
291 #define hal_diag_drain_serial hal_diag_drain_serial1 |
|
|
292 #define hal_diag_read_char_serial hal_diag_read_char_serial1 |
|
|
293 |
|
|
294 #endif |
|
|
295 |
|
|
296 #endif |
|
|
297 |
|
|
298 #if defined(CYG_HAL_MN10300_STDEVAL1) |
|
|
299 |
|
|
300 void led(int x) |
|
|
301 { |
|
|
302 *((cyg_uint8 *)0x36008004) = x<<4; |
|
|
303 } |
|
|
304 |
|
|
305 #endif |
|
|
306 |
|
|
307 |
|
|
308 /*---------------------------------------------------------------------------*/ |
|
|
309 |
|
|
310 #if defined(CYG_HAL_MN10300_STDEVAL1_SERIAL2) || defined(CYG_KERNEL_DIAG_SERIAL2) |
|
|
311 |
|
|
312 // We use serial2 on MN103002 |
|
|
313 #define SERIAL2_CR ((volatile cyg_uint16 *)0x34000820) |
|
|
314 #define SERIAL2_ICR ((volatile cyg_uint8 *) 0x34000824) |
|
|
315 #define SERIAL2_TXR ((volatile cyg_uint8 *) 0x34000828) |
|
|
316 #define SERIAL2_RXR ((volatile cyg_uint8 *) 0x34000829) |
|
|
317 #define SERIAL2_SR ((volatile cyg_uint8 *)0x3400082c) |
|
|
318 #define SERIAL2_TR ((volatile cyg_uint8 *)0x3400082d) |
|
|
319 |
|
|
320 // Timer 2 provided baud rate divisor |
|
|
321 #define TIMER2_MD ((volatile cyg_uint8 *)0x34001002) |
|
|
322 #define TIMER2_BR ((volatile cyg_uint8 *)0x34001012) |
|
|
323 #define TIMER2_CR ((volatile cyg_uint8 *)0x34001022) |
|
|
324 |
|
|
325 #define PORT3_MD ((volatile cyg_uint8 *)0x36008025) |
|
|
326 |
|
|
327 // Mystery register |
|
|
328 #define TMPSCNT ((volatile cyg_uint8 *)0x34001071) |
|
|
329 |
|
|
330 #define SIO2_LSTAT_TRDY 0x20 |
|
|
331 #define SIO2_LSTAT_RRDY 0x10 |
|
|
332 |
|
|
333 void hal_diag_init_serial2(void) |
|
|
334 { |
|
|
335 #if !defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) |
|
|
336 |
|
|
337 // 16 and 22 translate to 38400 baud. |
|
|
338 *TIMER2_BR = 16; |
|
|
339 *SERIAL2_TR = 22; |
|
|
340 |
|
|
341 // Timer2 sourced from IOCLK |
|
|
342 *TIMER2_MD = 0x80; |
|
|
343 |
|
|
344 // Mode on PORT3, used for serial line controls. |
|
|
345 *PORT3_MD = 0x01; |
|
|
346 |
|
|
347 // No interrupts for now. |
|
|
348 *SERIAL2_ICR = 0x00; |
|
|
349 |
|
|
350 // Source from timer 2, 8bit chars, enable tx and rx |
|
|
351 *SERIAL2_CR = 0xc081; |
|
|
352 |
|
|
353 #endif |
|
|
354 } |
|
|
355 |
|
|
356 void hal_diag_write_char_serial2(char c) |
|
|
357 { |
|
|
358 register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR; |
|
|
359 register volatile cyg_uint8 *volatile tty_tx = SERIAL2_TXR; |
|
|
360 |
|
|
361 while( (*tty_status & SIO2_LSTAT_TRDY) != 0 ) continue; |
|
|
362 |
|
|
363 *tty_tx = c; |
|
|
364 } |
|
|
365 |
|
|
366 void hal_diag_drain_serial2(void) |
|
|
367 { |
|
|
368 register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR; |
|
|
369 |
|
|
370 while( (*tty_status & SIO2_LSTAT_TRDY) != 0 ) continue; |
|
|
371 } |
|
|
372 |
|
|
373 void hal_diag_read_char_serial2(char *c) |
|
|
374 { |
|
|
375 register volatile cyg_uint8 *volatile tty_status = SERIAL2_SR; |
|
|
376 register volatile cyg_uint8 *volatile tty_rx = SERIAL2_RXR; |
|
|
377 |
|
|
378 while( (*tty_status & SIO2_LSTAT_RRDY) == 0 ) continue; |
|
|
379 |
|
|
380 *c = *tty_rx; |
|
|
381 } |
|
|
382 |
|
|
383 #if defined(CYG_KERNEL_DIAG_SERIAL2) |
|
|
384 |
|
|
385 #define hal_diag_init_serial hal_diag_init_serial2 |
|
|
386 #define hal_diag_write_char_serial hal_diag_write_char_serial2 |
|
|
387 #define hal_diag_drain_serial hal_diag_drain_serial2 |
|
|
388 #define hal_diag_read_char_serial hal_diag_read_char_serial2 |
|
|
389 |
|
|
390 #endif |
|
|
391 |
|
|
392 #endif |
|
|
393 |
|
|
394 /*---------------------------------------------------------------------------*/ |
|
|
395 |
|
|
396 void hal_diag_init(void) |
|
|
397 { |
|
|
398 hal_diag_init_serial(); |
|
|
399 } |
|
|
400 |
|
|
401 void hal_diag_write_char(char c) |
|
|
402 { |
|
|
403 #ifdef CYG_KERNEL_DIAG_GDB |
|
|
404 |
|
|
405 static char line[100]; |
|
|
406 static int pos = 0; |
|
|
407 |
|
|
408 // No need to send CRs |
|
|
409 if( c == '\r' ) return; |
|
|
410 |
|
|
411 line[pos++] = c; |
|
|
412 |
|
|
413 if( c == '\n' || pos == sizeof(line) ) |
|
|
414 { |
|
|
415 CYG_INTERRUPT_STATE old; |
|
|
416 |
|
|
417 // Disable interrupts. This prevents GDB trying to interrupt us |
|
|
418 // while we are in the middle of sending a packet. The serial |
|
|
419 // receive interrupt will be seen when we re-enable interrupts |
|
|
420 // later. |
|
|
421 |
|
|
422 HAL_DISABLE_INTERRUPTS(old); |
|
|
423 |
|
|
424 while(1) |
|
|
425 { |
|
|
426 static char hex[] = "0123456789ABCDEF"; |
|
|
427 cyg_uint8 csum = 0; |
|
|
428 int i; |
|
|
429 |
|
|
430 hal_diag_write_char_serial('$'); |
|
|
431 hal_diag_write_char_serial('O'); |
|
|
432 csum += 'O'; |
|
|
433 for( i = 0; i < pos; i++ ) |
|
|
434 { |
|
|
435 char ch = line[i]; |
|
|
436 char h = hex[(ch>>4)&0xF]; |
|
|
437 char l = hex[ch&0xF]; |
|
|
438 hal_diag_write_char_serial(h); |
|
|
439 hal_diag_write_char_serial(l); |
|
|
440 csum += h; |
|
|
441 csum += l; |
|
|
442 } |
|
|
443 hal_diag_write_char_serial('#'); |
|
|
444 hal_diag_write_char_serial(hex[(csum>>4)&0xF]); |
|
|
445 hal_diag_write_char_serial(hex[csum&0xF]); |
|
|
446 |
|
|
447 #if 0 |
|
|
448 { |
|
|
449 char c1; |
|
|
450 |
|
|
451 hal_diag_read_char_serial( &c1 ); |
|
|
452 |
|
|
453 // We must ack the interrupt caused by that read to avoid |
|
|
454 // confusing the GDB stub ROM. |
|
|
455 HAL_INTERRUPT_ACKNOWLEDGE( CYG_VECTOR_EXTERNAL_2 ); |
|
|
456 |
|
|
457 if( c1 == '+' ) break; |
|
|
458 |
|
|
459 ai_writes("hal_diag_read_char_serial("); |
|
|
460 ai_write_char(c1); |
|
|
461 ai_writes(")\r\n"); |
|
|
462 ai_writes("retry\r\n"); |
|
|
463 |
|
|
464 #if defined(CYG_HAL_USE_ROM_MONITOR) && defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) |
|
|
465 if( c1 == 3 ) |
|
|
466 { |
|
|
467 // Ctrl-C: breakpoint. |
|
|
468 // HAL_BREAKPOINT(_breakinst); |
|
|
469 typedef void bpt_fn(); |
|
|
470 bpt_fn *bfn = ((bpt_fn **)0x80000100)[61]; |
|
|
471 |
|
|
472 bfn(); |
|
|
473 |
|
|
474 break; |
|
|
475 } |
|
|
476 #endif |
|
|
477 |
|
|
478 } |
|
|
479 #else |
|
|
480 break; |
|
|
481 #endif |
|
|
482 } |
|
|
483 |
|
|
484 pos = 0; |
|
|
485 |
|
|
486 // Wait for tx buffer to drain |
|
|
487 hal_diag_drain_serial(); |
|
|
488 |
|
|
489 // And re-enable interrupts |
|
|
490 HAL_RESTORE_INTERRUPTS(old); |
|
|
491 |
|
|
492 } |
|
|
493 |
|
|
494 #else |
|
|
495 hal_diag_write_char_serial(c); |
|
|
496 #endif |
|
|
497 } |
|
|
498 |
|
|
499 |
|
|
500 |
|
|
501 |
|
|
502 void hal_diag_read_char(char *c) |
|
|
503 { |
|
|
504 hal_diag_read_char_serial(c); |
|
|
505 } |
|
|
506 |
|
|
507 |
|
|
508 /*---------------------------------------------------------------------------*/ |
|
|
509 /* End of hal_diag.c */ |