Mercurial > ecos
comparison packages/hal/powerpc/mbx/current/src/hal_diag.c @ 32:5af43b635655 ecos-sw-1999-08-18
Merge from eCos master repository on 1999-08-18-15:20:01-BST
| author | jlarmour |
|---|---|
| date | Wed, 18 Aug 1999 15:33:44 +0000 |
| parents | |
| children | 1370c5e55234 |
comparison
equal
deleted
inserted
replaced
| 31:e8319549378c | 32:5af43b635655 |
|---|---|
| 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,1999 Cygnus Solutions. All Rights Reserved. | |
| 26 // ------------------------------------------- | |
| 27 // | |
| 28 //####COPYRIGHTEND#### | |
| 29 //============================================================================= | |
| 30 //#####DESCRIPTIONBEGIN#### | |
| 31 // | |
| 32 // Author(s): hmt | |
| 33 // Contributors:hmt | |
| 34 // Date: 1999-06-08 | |
| 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_io.h> // IO macros | |
| 49 #include <cyg/hal/hal_diag.h> | |
| 50 #include <cyg/hal/hal_intr.h> // Interrupt macros | |
| 51 | |
| 52 #if defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS) | |
| 53 #include <cyg/hal/hal_stub.h> // hal_output_gdb_string | |
| 54 #endif | |
| 55 | |
| 56 #include <cyg/hal/ppc_regs.h> | |
| 57 #include <cyg/hal/quicc/quicc_smc1.h> | |
| 58 | |
| 59 //----------------------------------------------------------------------------- | |
| 60 // Select default diag channel to use | |
| 61 | |
| 62 //#define CYG_KERNEL_DIAG_ROMART | |
| 63 //#define CYG_KERNEL_DIAG_SERIAL | |
| 64 | |
| 65 #if !defined(CYG_KERNEL_DIAG_SERIAL) | |
| 66 #define CYG_KERNEL_DIAG_SERIAL | |
| 67 #endif | |
| 68 | |
| 69 #ifdef CYGDBG_DIAG_BUF | |
| 70 // Keep diag messages in a buffer for later [re]display | |
| 71 | |
| 72 int enable_diag_uart = 1; | |
| 73 int enable_diag_buf = 1; | |
| 74 static char diag_buf[40960*4]; | |
| 75 static int diag_buf_ptr = 0; | |
| 76 | |
| 77 static void | |
| 78 diag_putc(char c) | |
| 79 { | |
| 80 if (enable_diag_buf) { | |
| 81 diag_buf[diag_buf_ptr++] = c; | |
| 82 if (diag_buf_ptr == sizeof(diag_buf)) diag_buf_ptr--; | |
| 83 } | |
| 84 } | |
| 85 | |
| 86 void | |
| 87 dump_diag_buf(int start, int len) | |
| 88 { | |
| 89 int i; | |
| 90 enable_diag_uart = 1; | |
| 91 enable_diag_buf = 0; | |
| 92 if (len == 0) len = diag_buf_ptr; | |
| 93 diag_printf("\nDiag buf\n"); | |
| 94 for (i = start; i < len; i++) { | |
| 95 hal_diag_write_char(diag_buf[i]); | |
| 96 } | |
| 97 } | |
| 98 #endif // CYGDBG_DIAG_BUF | |
| 99 | |
| 100 | |
| 101 //----------------------------------------------------------------------------- | |
| 102 // MBX board specific serial output; using GDB protocol by default: | |
| 103 | |
| 104 | |
| 105 #if defined(CYG_KERNEL_DIAG_SERIAL) | |
| 106 | |
| 107 void hal_diag_init(void) | |
| 108 { | |
| 109 static int init = 0; | |
| 110 if (init) return; | |
| 111 init++; | |
| 112 // init the actual serial port | |
| 113 cyg_quicc_init_smc1(); | |
| 114 #ifndef CYG_HAL_STARTUP_ROM | |
| 115 // We are talking to GDB; ack the "go" packet! | |
| 116 cyg_quicc_smc1_uart_putchar('+'); | |
| 117 #endif | |
| 118 } | |
| 119 | |
| 120 void hal_diag_write_char_serial( char c ) | |
| 121 { | |
| 122 unsigned long __state; | |
| 123 HAL_DISABLE_INTERRUPTS(__state) | |
| 124 cyg_quicc_smc1_uart_putchar(c); | |
| 125 HAL_RESTORE_INTERRUPTS(__state); | |
| 126 } | |
| 127 | |
| 128 #ifdef CYG_HAL_STARTUP_ROM | |
| 129 void hal_diag_write_char(char c) | |
| 130 { | |
| 131 #ifdef CYGDBG_DIAG_BUF | |
| 132 diag_putc(c); | |
| 133 if (!enable_diag_uart) return; | |
| 134 #endif // CYGDBG_DIAG_BUF | |
| 135 hal_diag_write_char_serial(c); | |
| 136 } | |
| 137 | |
| 138 #else // RAM start so encode for GDB | |
| 139 | |
| 140 void hal_diag_write_char(char c) | |
| 141 { | |
| 142 static char line[100]; | |
| 143 static int pos = 0; | |
| 144 | |
| 145 #ifdef CYGDBG_DIAG_BUF | |
| 146 diag_putc(c); | |
| 147 if (!enable_diag_uart) return; | |
| 148 #endif // CYGDBG_DIAG_BUF | |
| 149 | |
| 150 // No need to send CRs | |
| 151 if( c == '\r' ) return; | |
| 152 | |
| 153 line[pos++] = c; | |
| 154 | |
| 155 if( c == '\n' || pos == sizeof(line) ) | |
| 156 { | |
| 157 CYG_INTERRUPT_STATE old; | |
| 158 | |
| 159 // Disable interrupts. This prevents GDB trying to interrupt us | |
| 160 // while we are in the middle of sending a packet. The serial | |
| 161 // receive interrupt will be seen when we re-enable interrupts | |
| 162 // later. | |
| 163 | |
| 164 HAL_DISABLE_INTERRUPTS(old); | |
| 165 | |
| 166 while(1) | |
| 167 { | |
| 168 static char hex[] = "0123456789ABCDEF"; | |
| 169 cyg_uint8 csum = 0; | |
| 170 int i; | |
| 171 | |
| 172 hal_diag_write_char_serial('$'); | |
| 173 hal_diag_write_char_serial('O'); | |
| 174 csum += 'O'; | |
| 175 for( i = 0; i < pos; i++ ) | |
| 176 { | |
| 177 char ch = line[i]; | |
| 178 char h = hex[(ch>>4)&0xF]; | |
| 179 char l = hex[ch&0xF]; | |
| 180 hal_diag_write_char_serial(h); | |
| 181 hal_diag_write_char_serial(l); | |
| 182 csum += h; | |
| 183 csum += l; | |
| 184 } | |
| 185 hal_diag_write_char_serial('#'); | |
| 186 hal_diag_write_char_serial(hex[(csum>>4)&0xF]); | |
| 187 hal_diag_write_char_serial(hex[csum&0xF]); | |
| 188 | |
| 189 #ifndef CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT | |
| 190 // only gobble characters if no interrupt handler to grab ^Cs | |
| 191 // is installed (which is exclusive with device driver use) | |
| 192 | |
| 193 // Wait for the ACK character '+' from GDB here and handle | |
| 194 // receiving a ^C instead. This is the reason for this clause | |
| 195 // being a loop. | |
| 196 c = cyg_quicc_smc1_uart_rcvchar(); | |
| 197 | |
| 198 if( c == '+' ) | |
| 199 break; // a good acknowledge | |
| 200 #if 0 | |
| 201 if( c1 == 3 ) { | |
| 202 // Ctrl-C: breakpoint. | |
| 203 breakpoint(); | |
| 204 break; | |
| 205 } | |
| 206 #endif | |
| 207 // otherwise, loop round again | |
| 208 #else | |
| 209 break; | |
| 210 #endif | |
| 211 } | |
| 212 | |
| 213 pos = 0; | |
| 214 | |
| 215 // And re-enable interrupts | |
| 216 HAL_RESTORE_INTERRUPTS(old); | |
| 217 | |
| 218 } | |
| 219 } | |
| 220 #endif // NOT def CYG_HAL_STARTUP_ROM | |
| 221 | |
| 222 | |
| 223 void hal_diag_read_char(char *c) | |
| 224 { | |
| 225 *c = cyg_quicc_smc1_uart_rcvchar(); | |
| 226 } | |
| 227 | |
| 228 #endif // CYG_KERNEL_DIAG_SERIAL | |
| 229 | |
| 230 // EOF hal_diag.c |
