Mercurial > ecos
annotate packages/hal/sparclite/sleb/current/src/hal_diag.c @ 4:1d7f19c9e4d1 ecos-sw-1999-05-11
Merge from eCos master repository on 1999-05-11-21:11:10-BST
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 14:07:25 +0000 |
| parents | 443894e2e912 |
| children | c38311975d4f |
| rev | line source |
|---|---|
| 2 | 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): 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/system.h> | |
| 43 #include <pkgconf/hal.h> | |
| 44 #include <pkgconf/hal_sparclite.h> | |
| 45 #include <pkgconf/hal_sparclite_sleb.h> | |
| 46 | |
| 47 #include <cyg/infra/cyg_type.h> // base types | |
| 48 | |
| 49 #include <cyg/hal/hal_arch.h> | |
| 50 #include <cyg/hal/hal_diag.h> | |
| 51 #include <cyg/hal/hal_intr.h> | |
| 52 | |
| 53 #include <cyg/hal/hal_cygm.h> | |
| 54 | |
| 55 /*---------------------------------------------------------------------------*/ | |
| 56 | |
| 57 #ifdef CYG_KERNEL_DIAG_GDB | |
| 58 | |
| 59 #ifdef CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT // then force $O packets to serial | |
| 60 | |
| 61 void hal_diag_init(void) | |
| 62 { | |
| 63 // hal_diag_init_serial(); | |
| 64 } | |
| 65 | |
| 66 void hal_diag_write_char_serial( char c ) | |
| 67 { | |
| 68 HAL_REORDER_BARRIER(); | |
| 69 HAL_DIAG_WRITE_CHAR_DIRECT( c ); | |
| 70 HAL_REORDER_BARRIER(); | |
| 71 HAL_DIAG_WRITE_CHAR_WAIT_FOR_EMPTY(); | |
| 72 HAL_REORDER_BARRIER(); | |
| 73 } | |
| 74 | |
| 75 void hal_diag_write_char(char c) | |
| 76 { | |
| 77 static char line[100]; | |
| 78 static int pos = 0; | |
| 79 | |
| 80 // No need to send CRs | |
| 81 if( c == '\r' ) return; | |
| 82 | |
| 83 line[pos++] = c; | |
| 84 | |
| 85 if( c == '\n' || pos == sizeof(line) ) | |
| 86 { | |
| 87 CYG_INTERRUPT_STATE old; | |
| 88 | |
| 89 // Disable interrupts. This prevents GDB trying to interrupt us | |
| 90 // while we are in the middle of sending a packet. The serial | |
| 91 // receive interrupt will be seen when we re-enable interrupts | |
| 92 // later. | |
| 93 | |
| 94 HAL_DISABLE_INTERRUPTS(old); | |
| 95 | |
| 96 while(1) | |
| 97 { | |
| 98 cyg_uint32 status, c1, tries; | |
| 99 static char hex[] = "0123456789ABCDEF"; | |
| 100 cyg_uint8 csum = 0; | |
| 101 int i; | |
| 102 | |
| 103 hal_diag_write_char_serial('$'); | |
| 104 hal_diag_write_char_serial('O'); | |
| 105 csum += 'O'; | |
| 106 for( i = 0; i < pos; i++ ) | |
| 107 { | |
| 108 char ch = line[i]; | |
| 109 char h = hex[(ch>>4)&0xF]; | |
| 110 char l = hex[ch&0xF]; | |
| 111 hal_diag_write_char_serial(h); | |
| 112 hal_diag_write_char_serial(l); | |
| 113 csum += h; | |
| 114 csum += l; | |
| 115 } | |
| 116 hal_diag_write_char_serial('#'); | |
| 117 hal_diag_write_char_serial(hex[(csum>>4)&0xF]); | |
| 118 hal_diag_write_char_serial(hex[csum&0xF]); | |
| 119 | |
| 120 // Wait for the ACK character '+' from GDB here and handle | |
| 121 // receiving a ^C instead. This is the reason for this clause | |
| 122 // being a loop. | |
| 123 status = 0; | |
| 124 tries = 1000000000; | |
| 125 while ( 0 == (HAL_SPARC_86940_FLAG_RXRDY & status) ) { | |
| 126 if ( 0 == --tries ) | |
| 127 break; | |
| 128 HAL_SPARC_86940_SDTR0_STAT_READ( status ); | |
| 129 } | |
| 130 if ( 0 == tries ) // then we broke out after waiting | |
| 131 continue; // the outer loop, send the packet | |
| 132 | |
| 133 HAL_SPARC_86940_SDTR0_RXDATA_READ( c1 ); | |
| 134 | |
| 135 // We must ack the interrupt caused by that read to avoid | |
| 136 // confusing the GDB stub ROM. | |
| 137 HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_VECTOR_INTERRUPT_10 ); | |
| 138 | |
| 139 if( c1 == '+' ) | |
| 140 break; // a good acknowledge | |
| 141 | |
| 142 if( c1 == 3 ) { | |
| 143 // Ctrl-C: breakpoint. | |
| 144 asm volatile( "ta 2; nop; nop; nop" ); | |
| 145 break; | |
| 146 } | |
| 147 // otherwise, loop round again | |
| 148 } | |
| 149 | |
| 150 pos = 0; | |
| 151 | |
| 152 // And re-enable interrupts | |
| 153 HAL_RESTORE_INTERRUPTS(old); | |
| 154 | |
| 155 } | |
| 156 } | |
| 157 #else // CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT not defined; use CygMon | |
| 158 | |
| 159 // All this code provided by MSalter - ta. | |
| 160 | |
| 161 struct bsp_comm_procs { | |
| 162 void *ch_data; | |
| 163 void (*__write)(void *ch_data, const char *buf, int len); | |
| 164 int (*__read)(void *ch_data, char *buf, int len); | |
| 165 void (*__putc)(void *ch_data, char ch); | |
| 166 int (*__getc)(void *ch_data); | |
| 167 int (*__control)(void *ch_data, int func, ...); | |
| 168 }; | |
| 169 | |
| 170 // This is pointed to by entry BSP_NOTVEC_BSP_COMM_PROCS: | |
| 171 typedef struct { | |
| 172 int version; /* version number for future expansion */ | |
| 173 void *__ictrl_table; | |
| 174 void *__exc_table; | |
| 175 void *__dbg_vector; | |
| 176 void *__kill_vector; | |
| 177 struct bsp_comm_procs *__console_procs; | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
178 struct bsp_comm_procs *__debug_procs; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
179 void *__flush_dcache; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
180 void *__flush_icache; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
181 void *__cpu_data; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
182 void *__board_data; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
183 void *__sysinfo; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
184 int (*__set_debug_comm)(int __comm_id); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
185 void *__set_console_comm; |
| 2 | 186 } bsp_shared_t; |
| 187 | |
| 188 | |
| 189 static int | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
190 hal_bsp_set_debug_comm(int arg) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
191 { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
192 bsp_shared_t *shared; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
193 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
194 shared = (bsp_shared_t *) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
195 (CYGMON_VECTOR_TABLE[ BSP_NOTVEC_BSP_COMM_PROCS ]); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
196 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
197 if (0 != shared->__set_debug_comm) { |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
198 return (*(shared->__set_debug_comm))(arg); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
199 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
200 return 0; |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
201 } |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
202 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
203 static int |
| 2 | 204 hal_bsp_console_write(const char *p, int len) |
| 205 { | |
| 206 bsp_shared_t *shared; | |
| 207 struct bsp_comm_procs *com; | |
| 208 | |
| 209 shared = (bsp_shared_t *) | |
| 210 (CYGMON_VECTOR_TABLE[ BSP_NOTVEC_BSP_COMM_PROCS ]); | |
| 211 | |
| 212 com = shared->__console_procs; | |
| 213 | |
| 214 if (0 != com) { | |
| 215 com->__write(com->ch_data, p, len); | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
216 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
217 #if 1 |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
218 // FIXME: This is a workaround for PR 19926; CygMon does not |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
219 // expect to be sharing the line with a serial driver (which |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
220 // can be excused :) and so doesn't acknowledge the interrupt. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
221 // In normal circumstances CygMon would handle the resulting |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
222 // interrupt and do the right thing. However, when using the |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
223 // serial driver it is handling the interrupts and gets |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
224 // mightily confused by these spurious interrupts. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
225 // |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
226 // As a workaround, ask CygMon which communication port is |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
227 // using for console output. If this is the serial port |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
228 // (comm 0), acknowledge the interrupt. |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
229 if ( 0 == hal_bsp_set_debug_comm( -1 ) ) |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
230 HAL_INTERRUPT_ACKNOWLEDGE( CYGNUM_HAL_VECTOR_INTERRUPT_10 ); |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
231 #endif |
|
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
232 |
| 2 | 233 return 1; |
| 234 } | |
| 235 return 0; | |
| 236 } | |
| 237 | |
| 238 static void | |
| 239 hal_dumb_serial_write(const char *p, int len) | |
| 240 { | |
| 241 int i; | |
| 242 for ( i = 0 ; i < len; i++ ) { | |
| 243 HAL_DIAG_WRITE_CHAR_DIRECT( p[ i ] ); | |
| 244 } | |
| 245 } | |
| 246 | |
| 247 | |
| 248 void hal_diag_init(void) | |
| 249 { | |
| 250 } | |
| 251 | |
| 252 void hal_diag_write_char(char c) | |
| 253 { | |
| 254 static char line[100]; | |
| 255 static int pos = 0; | |
| 256 | |
| 257 // No need to send CRs | |
| 258 if( c == '\r' ) return; | |
| 259 | |
| 260 line[pos++] = c; | |
| 261 | |
| 262 if( c == '\n' || pos == sizeof(line) ) { | |
| 263 CYG_INTERRUPT_STATE old; | |
| 264 | |
| 265 // Disable interrupts. This prevents GDB trying to interrupt us | |
| 266 // while we are in the middle of sending a packet. The serial | |
| 267 // receive interrupt will be seen when we re-enable interrupts | |
| 268 // later. | |
| 269 | |
| 270 HAL_DISABLE_INTERRUPTS(old); | |
| 271 | |
| 272 if ( ! hal_bsp_console_write( line, pos ) ) | |
| 273 // then there is no function registered, just spew it out serial | |
| 274 hal_dumb_serial_write( line, pos ); | |
| 275 | |
| 276 pos = 0; | |
| 277 | |
| 278 // And re-enable interrupts | |
| 279 HAL_RESTORE_INTERRUPTS(old); | |
|
4
1d7f19c9e4d1
Merge from eCos master repository on 1999-05-11-21:11:10-BST
jlarmour
parents:
2
diff
changeset
|
280 |
| 2 | 281 } |
| 282 } | |
| 283 | |
| 284 #endif // CYG_KERNEL_DIAG_GDB_SERIAL_DIRECT not defined; use CygMon | |
| 285 | |
| 286 #else // CYG_KERNEL_DIAG_GDB not defined, so we are going to the serial line | |
| 287 // without GDB encoding - likely to be ROM startup. | |
| 288 | |
| 289 /* Address of clock switch */ | |
| 290 #define CLKSW_ADDR 0x01000003 | |
| 291 | |
| 292 /* Address of SW1 */ | |
| 293 #define SW1_ADDR 0x02000003 | |
| 294 | |
| 295 void hal_diag_init(void) | |
| 296 { | |
| 297 cyg_uint32 clk, tval; | |
| 298 | |
| 299 // first set the baud rate | |
| 300 | |
| 301 clk = *(unsigned char *)CLKSW_ADDR; | |
| 302 if (clk & 0x80) | |
| 303 clk = 10; | |
| 304 | |
| 305 clk = (clk & 0x3f) * 1000000; /* in MHz */ | |
| 306 | |
| 307 tval = clk / 19200; | |
| 308 tval /= 32; | |
| 309 tval -= 1; | |
| 310 | |
| 311 HAL_SPARC_86940_TCR3_WRITE( | |
| 312 HAL_SPARC_86940_TCR_CE | | |
| 313 HAL_SPARC_86940_TCR_CLKINT | | |
| 314 HAL_SPARC_86940_TCR_OUTC3 | | |
| 315 HAL_SPARC_86940_TCR_SQWAVE ); | |
| 316 | |
| 317 HAL_SPARC_86940_RELOAD3_WRITE( tval); | |
| 318 | |
| 319 #define DELAY(x) \ | |
| 320 CYG_MACRO_START int i; for (i = 0; i < x; i++); CYG_MACRO_END | |
| 321 | |
| 322 HAL_SPARC_86940_SDTR0_CTRL_WRITE( 0 ); | |
| 323 DELAY(100); | |
| 324 HAL_SPARC_86940_SDTR0_CTRL_WRITE( 0 ); | |
| 325 DELAY(100); | |
| 326 HAL_SPARC_86940_SDTR0_CTRL_WRITE( 0 ); | |
| 327 DELAY(100); | |
| 328 | |
| 329 HAL_SPARC_86940_SDTR0_CTRL_WRITE( HAL_SPARC_86940_SER_CMD_IRST ); | |
| 330 DELAY(100); | |
| 331 | |
| 332 /* first write after reset is to mode register */ | |
| 333 HAL_SPARC_86940_SDTR0_CTRL_WRITE( HAL_SPARC_86940_SER_DIV16_CLK | | |
| 334 HAL_SPARC_86940_SER_8BITS | | |
| 335 HAL_SPARC_86940_SER_NO_PARITY | | |
| 336 HAL_SPARC_86940_SER_STOP1 ); | |
| 337 DELAY(100); | |
| 338 | |
| 339 /* subsequent writes are to command register */ | |
| 340 HAL_SPARC_86940_SDTR0_CTRL_WRITE( HAL_SPARC_86940_SER_CMD_RTS | | |
| 341 HAL_SPARC_86940_SER_CMD_DTR | | |
| 342 HAL_SPARC_86940_SER_CMD_EFR | | |
| 343 HAL_SPARC_86940_SER_CMD_RXEN | | |
| 344 HAL_SPARC_86940_SER_CMD_TXEN ); | |
| 345 DELAY(100); | |
| 346 } | |
| 347 | |
| 348 | |
| 349 | |
| 350 | |
| 351 | |
| 352 #endif // CYG_KERNEL_DIAG_GDB | |
| 353 | |
| 354 /*---------------------------------------------------------------------------*/ | |
| 355 /* End of hal_diag.c */ |
