1 /* 2 ****************************************************************************** 3 ****************************************************************************** 4 * 5 * COPYRIGHT (C) by EMC Corporation, 1997 All rights reserved. 6 * $Id: gdb_c_test.c,v 1.3 2004/12/27 14:01:00 kettenis Exp $ 7 * DESCRIPTION: This module has been provided for the purpose of testing GDB. 8 * 9 * NOTES: 10 * 11 ****************************************************************************** 12 *****************************************************************************/ 13 14 /*============================================================================= 15 * INCLUDE FILES 16 *===========================================================================*/ 17 18 19 #ifdef DO_IT_BY_THE_BOOK 20 21 22 #include "symtypes_defs.h" 23 #include "printp.h" 24 25 #include "adbg_expression.h" 26 #include "common_hw_ds.h" 27 #include "common_hw_defs.h" 28 #include "evnttrac.h" 29 #include "sym_scratch_ds.h" 30 #include "symglob_ds.h" 31 #include "sym_protglob_ds.h" 32 33 #include "ether.h" 34 35 #include <ctype.h> 36 37 38 #else 39 40 #include "adbg_dtc.h" 41 42 #define YES 1 43 #define NO 0 44 45 #define TRUE 1 46 #define FALSE 0 47 48 #define ENABLED 1 49 #define DISABLED 0 50 51 #define CONTROL_C 3 /* ASCII 'ETX' */ 52 53 54 /* 55 * Faked after ctype.h 56 */ 57 58 #define isxdigit(X) (((X) >= '0' && (X) <= '9') || \ 59 ((X) >= 'A' && (X) <= 'F') || \ 60 ((X) >= 'a' && (X) <= 'f')) 61 /* 62 * Borrowed from string.h 63 */ 64 65 extern unsigned int strlen ( const char * ); 66 67 /* 68 * Extracted from symtypes.h: 69 */ 70 71 typedef char BOOL; /* 8 Bits */ 72 typedef unsigned char UCHAR; /* 8 Bits */ 73 typedef unsigned short USHORT; /* 16 Bits */ 74 typedef unsigned long ULONG; /* 32 Bits */ 75 76 /* 77 * for struct t_expr_tag and 78 * decl of build_and_add_expression 79 */ 80 #include "adbg_expression.h" 81 #define NULL 0 82 83 /* 84 * Extracted from printp.h: 85 */ 86 87 extern void printp ( const char * fptr, ... ); 88 extern void sprintp ( const char * fptr, ... ); 89 90 /* 91 * Extracted from ether.h: 92 */ 93 94 extern long eth_to_gdb ( UCHAR *buf, long length ); 95 96 97 /* 98 * Derived from hwequs.s: 99 */ 100 101 #define CS_CODE_START 0x100000 102 #define CS_CODE_SIZE 0x200000 103 #define LAST_CS_WORD (CS_CODE_START + CS_CODE_SIZE - 2) 104 105 #define sh_genstat1 (*((volatile ULONG *) 0xFFFFFE54)) 106 107 #define rs232_mode1 0 /* rs-232 mode 1 reg. */ 108 #define rs232_mode2 rs232_mode1 /* rs-232 mode 2 reg. */ 109 #define rs232_stat 4 /* rs-232 status reg. */ 110 #define rs232_clk rs232_stat /* rs-232 clock select reg. */ 111 #define rs232_cmd 8 /* rs-232 command reg */ 112 #define rs232_transmit 12 /* rs-232 transmit reg. */ 113 #define rs232_receive rs232_transmit /* rs-232 transmit reg. */ 114 #define rs232_aux 16 /* rs-232 aux control reg. */ 115 #define rs232_isr 20 /* rs-232 interrupt status reg. */ 116 #define rs232_imr rs232_isr /* rs-232 interrupt mask reg. */ 117 #define rs232_tc_high 24 /* rs-232 timer/counter high reg. */ 118 #define rs232_tc_low 28 /* rs-232 timer/counter low reg. */ 119 120 121 #endif 122 123 124 /*============================================================================ 125 * MODULE DEFINES 126 *===========================================================================*/ 127 128 #define P_RST_LAN_UART_REG ((volatile UCHAR *) 0xFFFFFE45) 129 #define M_RST_LAN_UART 0x80 /* Bit 7 */ 130 131 #define P_LAN0TR_REG P_RST_LAN_UART_REG 132 #define M_LAN0TR 0x20 /* Bit 5 */ 133 134 #define M_SH_GENCON_LAN0TR 0x00200000 /* Bit 21 */ 135 136 #define MAX_RS232_CHARS 512 137 138 #define LAN_Q_MOD(X) ((X) % MAX_RS232_CHARS) 139 140 /*---------------------------------------* 141 * LAN UART Registers * 142 *---------------------------------------*/ 143 144 #define LAN_UART_BASE ((ULONG) 0xfffffc22) 145 146 /* Write-Read */ 147 148 #define P_LAN_MR1 ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode1 ))) 149 #define P_LAN_MR2 ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_mode2 ))) 150 151 /* Write-Only */ 152 153 #define P_LAN_ACR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_aux ))) 154 #define P_LAN_CR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_cmd ))) 155 #define P_LAN_CSR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_clk ))) 156 #define P_LAN_CTLR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_low ))) 157 #define P_LAN_CTUR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_tc_high ))) 158 #define P_LAN_IMR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_imr ))) 159 160 /* Read-Only */ 161 162 #define P_LAN_SR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_stat ))) 163 #define P_LAN_ISR ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_isr ))) 164 #define P_LAN_XMT ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_transmit))) 165 #define P_LAN_RCV ((volatile UCHAR *) (LAN_UART_BASE + ((ULONG) rs232_receive ))) 166 167 /* 168 * Bit Values for Write-Read and Write-Only Registers 169 */ 170 171 #define DEFAULT_LAN_MR1 ((UCHAR) 0x13) 172 #define DEFAULT_LAN_MR2 ((UCHAR) 0x07) 173 #define DEFAULT_LAN_CSR ((UCHAR) 0xcc) 174 #define DEFAULT_LAN_ACR ((UCHAR) 0x38) 175 #define DEFAULT_LAN_CTUR ((UCHAR) 0xff) 176 #define DEFAULT_LAN_CTLR ((UCHAR) 0xff) 177 178 #define LAN_ACR_SELECT_BRG_0 DEFAULT_LAN_ACR 179 #define LAN_ACR_SELECT_BRG_1 (DEFAULT_LAN_ACR | 0x80) 180 181 #define UART_CR_RESET_MR_PTR ((UCHAR) 0x10) /* Reset MR pointer (points to MR1). */ 182 #define UART_CR_RESET_RVCR ((UCHAR) 0x20) /* Reset receiver (disabled). */ 183 #define UART_CR_RESET_XMTR ((UCHAR) 0x30) /* Reset transmitter (disabled). */ 184 #define UART_CR_RESET_ERROR_STATUS ((UCHAR) 0x40) /* Reset error status. */ 185 #define UART_CR_RESET_BRK_CHG_INT ((UCHAR) 0x50) /* Reset break change interrupt. */ 186 #define UART_CR_START_CNTR_TIMER ((UCHAR) 0x80) /* Start counter/timer. */ 187 #define UART_CR_STOP_CNTR ((UCHAR) 0x90) /* Stop counter. */ 188 189 #define UART_CR_DISABLE_XMTR ((UCHAR) 0x08) /* Disable transmitter. */ 190 #define UART_CR_ENABLE_XMTR ((UCHAR) 0x04) /* Enable transmitter. */ 191 #define UART_CR_DISABLE_RCVR ((UCHAR) 0x02) /* Disable receiver. */ 192 #define UART_CR_ENABLE_RCVR ((UCHAR) 0x01) /* Enable receiver. */ 193 194 #define UART_CSR_BR_4800 ((UCHAR) 0x99) /* With either BRG Set selected (via ACR). */ 195 #define UART_CSR_BR_9600 ((UCHAR) 0xbb) /* With either BRG Set selected (via ACR). */ 196 #define UART_CSR_BR_19200 ((UCHAR) 0xcc) /* With BRG Set '1' selected (via ACR). */ 197 #define UART_CSR_BR_38400 ((UCHAR) 0xcc) /* With BRG Set '0' selected (via ACR). */ 198 199 #define UART_IMR_RxRDY ((UCHAR) 0x04) /* Enable 'RxRDY' interrupt. */ 200 #define UART_IMR_TxEMT ((UCHAR) 0x02) /* Enable 'TxEMT' interrupt. */ 201 #define UART_IMR_TxRDY ((UCHAR) 0x01) /* Enable 'TxRDY' interrupt. */ 202 203 /* 204 * Bit Masks for Read-Only Registers 205 */ 206 207 #define M_UART_SR_RCVD_BRK 0x80 /* Bit 7 */ 208 #define M_UART_SR_FE 0x40 /* Bit 6 */ 209 #define M_UART_SR_PE 0x20 /* Bit 5 */ 210 #define M_UART_SR_OE 0x10 /* Bit 4 */ 211 #define M_UART_SR_TxEMT 0x08 /* Bit 3 */ 212 #define M_UART_SR_TxRDY 0x04 /* Bit 2 */ 213 #define M_UART_SR_FFULL 0x02 /* Bit 1 */ 214 #define M_UART_SR_RxRDY 0x01 /* Bit 0 */ 215 216 #define M_UART_ISR_RxRDY 0x04 /* Bit 2 */ 217 #define M_UART_ISR_TxEMT 0x02 /* Bit 1 */ 218 #define M_UART_ISR_TxRDY 0x01 /* Bit 0 */ 219 220 /*---------------------------------------* 221 * Support for 'Utility 83'. * 222 *---------------------------------------*/ 223 224 #define LAN_UTIL_CODE 0x83 225 226 #define LAN_INIT ((ULONG) (('I' << 24) | ('N' << 16) | ('I' << 8) | 'T')) 227 #define LAN_BAUD ((ULONG) (('B' << 24) | ('A' << 16) | ('U' << 8) | 'D')) 228 #define LAN_INTR ((ULONG) (('I' << 24) | ('N' << 16) | ('T' << 8) | 'R')) 229 #define LAN_XMT ((ULONG) (('X' << 16) | ('M' << 8) | 'T')) 230 #define LAN_ECHO ((ULONG) (('E' << 24) | ('C' << 16) | ('H' << 8) | 'O')) 231 #define LAN_STAT ((ULONG) (('S' << 24) | ('T' << 16) | ('A' << 8) | 'T')) 232 #define LAN_IN ((ULONG) (('I' << 8) | 'N')) 233 #define LAN_OUT ((ULONG) (('O' << 16) | ('U' << 8) | 'T')) 234 235 #define LAN_PUTC ((ULONG) (('P' << 24) | ('U' << 16) | ('T' << 8) | 'C')) 236 #define LAN_WPM ((ULONG) (('W' << 16) | ('P' << 8) | 'M')) 237 238 #define STATUS(X) ( ( ( X ) == 0 ) ? "disabled" : "enabled" ) 239 240 #define XMT_VIA_BP_ENABLED() ( *P_LAN0TR_REG & M_LAN0TR ? 1 : 0 ) 241 242 #define TRAP_1_INST 0x4E41 243 244 /* 245 * Bit #13 of shared genstat 1 indicates 246 * which processor we are as follows. 247 * 248 * 0 => X (side A) 249 * 1 => Y (side B) 250 */ 251 252 #define M_PROC_ID 0x00002000 253 254 #define IS_SIDE_A() ( ( (sh_genstat1) & M_PROC_ID ) == 0 ) 255 #define IS_SIDE_B() ( (sh_genstat1) & M_PROC_ID ) 256 257 258 #ifdef STANDALONE /* Compile this module stand-alone for debugging */ 259 #define LAN_PUT_CHAR(X) printf("%c", X) 260 #else 261 #define LAN_PUT_CHAR(X) while ( lan_put_char( X ) ) 262 #endif 263 264 265 266 267 #define VIA_RS232 0 268 #define VIA_ETHERNET 1 269 270 #define MAX_IO_BUF_SIZE 400 271 272 #define MAX_BYTE_CODES 200 /* maximum length for bytecode string */ 273 274 275 static ULONG gdb_host_comm; 276 277 static ULONG gdb_cat_ack; 278 279 static char eth_outbuffer[ MAX_IO_BUF_SIZE + 1 ]; 280 281 282 #ifdef STANDALONE 283 284 #define ACK_PKT() LAN_PUT_CHAR( '+' ) 285 #define NACK_PKT() LAN_PUT_CHAR( '-' ) 286 287 #else 288 289 #define ACK_PKT() { \ 290 if ( VIA_ETHERNET == gdb_host_comm ) \ 291 { \ 292 gdb_cat_ack = YES; \ 293 } \ 294 else \ 295 { \ 296 LAN_PUT_CHAR( '+' ); \ 297 } \ 298 } 299 300 301 302 #define NACK_PKT() { \ 303 if ( VIA_ETHERNET == gdb_host_comm ) \ 304 { \ 305 eth_outbuffer[ 0 ] = '-'; \ 306 eth_to_gdb( (UCHAR *) eth_outbuffer, 1 ); \ 307 } \ 308 else \ 309 { \ 310 LAN_PUT_CHAR( '-' ); \ 311 } \ 312 } 313 314 #endif 315 316 317 318 319 /*============================================================================ 320 * MODULE TYPEDEFS 321 *===========================================================================*/ 322 323 typedef struct rs232_queue { 324 325 long head_index; 326 327 long tail_index; 328 329 ULONG overflows; 330 331 long gdb_packet_start; 332 long gdb_packet_end; 333 long gdb_packet_csum1; 334 long gdb_packet_csum2; 335 336 UCHAR buf[ MAX_RS232_CHARS ]; 337 338 } T_RS232_QUEUE; 339 340 341 342 343 /*============================================================================= 344 * EXTERNAL GLOBAL VARIABLES 345 *===========================================================================*/ 346 347 extern volatile UCHAR sss_trace_flag; 348 349 350 /*============================================================================= 351 * STATIC MODULE DECLARATIONS 352 *===========================================================================*/ 353 354 static T_RS232_QUEUE lan_input_queue, 355 lan_output_queue; 356 357 static BOOL test_echo; 358 359 #if 0 360 /* The stub no longer seems to use this. */ 361 static BOOL write_access_enabled; 362 #endif 363 364 static int baud_rate_idx; 365 366 static ULONG tx_by_intr, 367 tx_by_poll; 368 369 static UCHAR lan_shadow_imr; 370 371 372 /*============================================================================= 373 * EXTERNAL FUNCTION PROTOTYPES 374 *===========================================================================*/ 375 376 extern long write_to_protected_mem( void *address, unsigned short value ); 377 378 379 /*============================================================================= 380 * MODULE GLOBAL FUNCTIONS PROTOTYPES 381 *===========================================================================*/ 382 383 ULONG gdb_c_test( ULONG *parm ); 384 385 386 void lan_init( void ); 387 388 void lan_isr( void ); 389 390 long lan_get_char( void ); 391 392 long lan_put_char( UCHAR c ); 393 394 ULONG lan_util( ULONG *parm ); 395 396 397 /*============================================================================= 398 * MODULE LOCAL FUNCTION PROTOTYPES 399 *===========================================================================*/ 400 401 static void lan_reset( void ); 402 403 static void lan_configure( void ); 404 405 static void lan_init_queue( T_RS232_QUEUE *p_queue ); 406 407 static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue ); 408 409 static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue ); 410 411 static void lan_util_menu( void ); 412 413 static long get_gdb_input( long c, T_RS232_QUEUE *p_input_q ); 414 415 416 /*============================================================================= 417 * GDB STUB FUNCTION PROTOTYPES 418 *===========================================================================*/ 419 420 void gdb_trap_1_handler( void ); 421 void gdb_trace_handler ( void ); 422 423 void gdb_get_eth_input( unsigned char *buf, long length ); 424 425 static void getpacket ( void ); 426 static void putpacket ( char * ); 427 static void discard_packet ( void ); 428 429 #ifdef STANDALONE /* Compile this module stand-alone for debugging */ 430 #include <stdio.h> 431 #define printp printf /* easier than declaring a local varargs stub func. */ 432 #endif /* STANDALONE */ 433 434 435 /*============================================================================= 436 * MODULE BODY 437 *===========================================================================*/ 438 439 /* ------------------- Things that belong in a header file --------------- */ 440 extern char *memset (char *, int, int); 441 442 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* 443 * * 444 * Global Module Functions * 445 * * 446 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 447 448 449 static char gdb_char_test; 450 static short gdb_short_test; 451 static long gdb_long_test; 452 static char gdb_arr_test[25]; 453 static struct GDB_STRUCT_TEST 454 { 455 char c; 456 short s; 457 long l; 458 int bfield : 11; /* collect bitfield */ 459 char arr[25]; 460 struct GDB_STRUCT_TEST *next; 461 } gdb_struct1_test, gdb_struct2_test, *gdb_structp_test, **gdb_structpp_test; 462 463 static union GDB_UNION_TEST 464 { 465 char c; 466 short s; 467 long l; 468 int bfield : 11; /* collect bitfield */ 469 char arr[4]; 470 union GDB_UNION_TEST *next; 471 } gdb_union1_test; 472 473 void gdb_recursion_test (int, int, int, int, int, int, int); 474 475 void gdb_recursion_test (int depth, 476 int q1, 477 int q2, 478 int q3, 479 int q4, 480 int q5, 481 int q6) 482 { /* gdb_recursion_test line 0 */ 483 int q = q1; /* gdbtestline 1 */ 484 485 q1 = q2; /* gdbtestline 2 */ 486 q2 = q3; /* gdbtestline 3 */ 487 q3 = q4; /* gdbtestline 4 */ 488 q4 = q5; /* gdbtestline 5 */ 489 q5 = q6; /* gdbtestline 6 */ 490 q6 = q; /* gdbtestline 7 */ 491 if (depth--) /* gdbtestline 8 */ 492 gdb_recursion_test (depth, q1, q2, q3, q4, q5, q6); /* gdbtestline 9 */ 493 } 494 495 496 ULONG gdb_c_test( ULONG *parm ) 497 498 { 499 char *p = "gdb_c_test"; 500 char *ridiculously_long_variable_name_with_equally_long_string_assignment; 501 register long local_reg = 7; 502 static unsigned long local_static, local_static_sizeof; 503 long local_long; 504 unsigned long *stack_ptr; 505 unsigned long end_of_stack; 506 507 ridiculously_long_variable_name_with_equally_long_string_assignment = 508 "ridiculously long variable name with equally long string assignment"; 509 local_static = 9; 510 local_static_sizeof = sizeof (struct GDB_STRUCT_TEST); 511 local_long = local_reg + 1; 512 stack_ptr = (unsigned long *) &local_long; 513 end_of_stack = 514 (unsigned long) &stack_ptr + sizeof(stack_ptr) + sizeof(end_of_stack) - 1; 515 516 printp ("\n$Id: gdb_c_test.c,v 1.3 2004/12/27 14:01:00 kettenis Exp $\n"); 517 518 printp( "%s: arguments = %X, %X, %X, %X, %X, %X\n", 519 p, parm[ 1 ], parm[ 2 ], parm[ 3 ], parm[ 4 ], parm[ 5 ], parm[ 6 ] ); 520 521 gdb_char_test = gdb_struct1_test.c = (char) ((long) parm[1] & 0xff); 522 gdb_short_test = gdb_struct1_test.s = (short) ((long) parm[2] & 0xffff); 523 gdb_long_test = gdb_struct1_test.l = (long) ((long) parm[3] & 0xffffffff); 524 gdb_union1_test.l = (long) parm[4]; 525 gdb_arr_test[0] = gdb_struct1_test.arr[0] = (char) ((long) parm[1] & 0xff); 526 gdb_arr_test[1] = gdb_struct1_test.arr[1] = (char) ((long) parm[2] & 0xff); 527 gdb_arr_test[2] = gdb_struct1_test.arr[2] = (char) ((long) parm[3] & 0xff); 528 gdb_arr_test[3] = gdb_struct1_test.arr[3] = (char) ((long) parm[4] & 0xff); 529 gdb_arr_test[4] = gdb_struct1_test.arr[4] = (char) ((long) parm[5] & 0xff); 530 gdb_arr_test[5] = gdb_struct1_test.arr[5] = (char) ((long) parm[6] & 0xff); 531 gdb_struct1_test.bfield = 144; 532 gdb_struct1_test.next = &gdb_struct2_test; 533 gdb_structp_test = &gdb_struct1_test; 534 gdb_structpp_test = &gdb_structp_test; 535 536 gdb_recursion_test (3, (long) parm[1], (long) parm[2], (long) parm[3], 537 (long) parm[4], (long) parm[5], (long) parm[6]); 538 539 gdb_char_test = gdb_short_test = gdb_long_test = 0; 540 gdb_structp_test = (void *) 0; 541 gdb_structpp_test = (void *) 0; 542 memset ((char *) &gdb_struct1_test, 0, sizeof (gdb_struct1_test)); 543 memset ((char *) &gdb_struct2_test, 0, sizeof (gdb_struct2_test)); 544 local_static_sizeof = 0; 545 local_static = 0; 546 return ( (ULONG) 0 ); 547 } 548 549 550 /*----------------------------------------------------------------------------- 551 * 552 * FUNCTION NAME: lan_init 553 * 554 * 555 * DESCRIPTION: 556 * 557 * 558 * RETURN VALUE: 559 * 560 * 561 * USED GLOBAL VARIABLES: 562 * 563 * 564 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 565 * 566 * 567 * NOTES: 568 * 569 * 570 * 571 *---------------------------------------------------------------------------*/ 572 573 void lan_init( void ) 574 575 { 576 577 if ( IS_SIDE_A( ) ) 578 { 579 580 lan_reset( ); 581 582 lan_init_queue( &lan_input_queue ); 583 584 lan_init_queue( &lan_output_queue ); 585 586 lan_configure( ); 587 } 588 589 return; 590 } 591 /* end of 'lan_init' 592 *===========================================================================*/ 593 594 595 /*----------------------------------------------------------------------------- 596 * 597 * FUNCTION NAME: lan_isr 598 * 599 * 600 * DESCRIPTION: 601 * 602 * 603 * RETURN VALUE: None. 604 * 605 * 606 * USED GLOBAL VARIABLES: 607 * 608 * 609 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 610 * 611 * 612 * NOTES: 613 * 614 * 615 *---------------------------------------------------------------------------*/ 616 617 void lan_isr( void ) 618 619 { 620 UCHAR c; 621 622 623 lan_shadow_imr = 0; /* Disable all UART interrupts. */ 624 *P_LAN_IMR = lan_shadow_imr; 625 626 627 if ( *P_LAN_ISR & M_UART_ISR_RxRDY ) 628 { 629 630 gdb_host_comm = VIA_RS232; 631 632 c = *P_LAN_RCV; 633 634 if ( test_echo ) 635 { 636 /* ????? */ 637 } 638 639 if ( c == CONTROL_C ) 640 { 641 /* can't stop the target, but we can tell gdb to stop waiting... */ 642 discard_packet( ); 643 putpacket( "S03" ); /* send back SIGINT to the debugger */ 644 } 645 646 else 647 { 648 lan_add_to_queue( (long) c, &lan_input_queue ); 649 get_gdb_input( (long) c, &lan_input_queue ); 650 } 651 652 } 653 654 if ( XMT_VIA_BP_ENABLED( ) ) 655 { 656 657 c = 0; 658 659 while ( (*P_LAN_ISR & M_UART_ISR_TxRDY) && (c = lan_next_queue_char( &lan_output_queue )) ) 660 { 661 *P_LAN_XMT = c; 662 ++tx_by_intr; 663 } 664 665 if ( c ) 666 { 667 lan_shadow_imr |= UART_IMR_TxRDY; /* (Re-)Enable 'TxRDY' interrupt from UART. */ 668 } 669 670 } 671 672 673 lan_shadow_imr |= UART_IMR_RxRDY; /* Re-Enable 'RxRDY' interrupt from UART. */ 674 *P_LAN_IMR = lan_shadow_imr; 675 676 677 678 return; 679 } 680 /* end of 'lan_isr' 681 *===========================================================================*/ 682 683 684 /*----------------------------------------------------------------------------- 685 * 686 * FUNCTION NAME: lan_get_char 687 * 688 * 689 * DESCRIPTION: Fetches a character from the UART. 690 * 691 * 692 * RETURN VALUE: 0 on success, -1 on failure. 693 * 694 * 695 * USED GLOBAL VARIABLES: 696 * 697 * 698 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 699 * 700 * 701 * NOTES: 702 * 703 * 704 *---------------------------------------------------------------------------*/ 705 706 long lan_get_char( void ) 707 708 { 709 long status = -2; /* AGD: nothing found in rcv buffer */ 710 711 if ( *P_LAN_SR & M_UART_SR_RxRDY ) 712 { 713 char c = (char) *P_LAN_RCV; 714 715 if ( test_echo ) 716 { 717 LAN_PUT_CHAR ( c ); 718 } 719 720 if ( c == CONTROL_C ) 721 { 722 /* can't stop the target, but we can tell gdb to stop waiting... */ 723 discard_packet( ); 724 putpacket( "S03" ); /* send back SIGINT to the debugger */ 725 status = 0; /* success */ 726 } 727 728 else 729 { 730 lan_add_to_queue( (long) c, &lan_input_queue ); 731 status = get_gdb_input( (long) c, &lan_input_queue ); 732 } 733 734 } 735 736 return( status ); 737 } 738 /* end of 'lan_get_char' 739 *===========================================================================*/ 740 741 742 /*----------------------------------------------------------------------------- 743 * 744 * FUNCTION NAME: lan_put_char 745 * 746 * DESCRIPTION: Puts a character out via the UART. 747 * 748 * RETURN VALUE: 0 on success, -1 on failure. 749 * 750 * USED GLOBAL VARIABLES: none. 751 * 752 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 753 * 754 * NOTES: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 755 * !! !! 756 * !! If 'XMT_VIA_BP_ENABLED()' is FALSE then output is THROWN AWAY. !! 757 * !! This prevents anyone infinite-looping on this function. !! 758 * !! !! 759 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 760 * 761 *---------------------------------------------------------------------------*/ 762 763 long lan_put_char( UCHAR c ) 764 765 { 766 long status = -1; 767 768 if ( XMT_VIA_BP_ENABLED( ) ) 769 { 770 771 if ( *P_LAN_SR & M_UART_SR_TxRDY ) 772 { 773 lan_add_to_queue( (long) c, &lan_output_queue ); 774 775 c = lan_next_queue_char( &lan_output_queue ); 776 777 *P_LAN_XMT = c; 778 ++tx_by_poll; 779 status = 0; 780 } 781 #if 0 782 else 783 { 784 status = 0; 785 lan_shadow_imr |= UART_IMR_TxRDY; /* Enable 'TxRDY' interrupt from UART. */ 786 *P_LAN_IMR = lan_shadow_imr; 787 } 788 #endif 789 } 790 791 else 792 { 793 status = 0; /* You lose: input character goes to the bit bucket. */ 794 } 795 796 return( status ); 797 } 798 /* end of 'lan_put_char' 799 *===========================================================================*/ 800 801 802 /*----------------------------------------------------------------------------- 803 * 804 * FUNCTION NAME: lan_util 805 * 806 * DESCRIPTION: 807 * 808 * RETURN VALUE: 809 * 810 * USED GLOBAL VARIABLES: 811 * 812 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 813 * 814 * NOTES: 815 * 816 *---------------------------------------------------------------------------*/ 817 818 ULONG lan_util( ULONG *parm ) 819 820 { 821 822 823 static const struct { 824 825 ULONG rate_code; 826 UCHAR acr_setting; 827 UCHAR csr_setting; 828 829 } baud_rate_setting [] = { 830 831 { 0x38400, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_38400 }, 832 { 0x19200, LAN_ACR_SELECT_BRG_1, UART_CSR_BR_19200 }, 833 { 0x9600, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_9600 }, 834 { 0x4800, LAN_ACR_SELECT_BRG_0, UART_CSR_BR_4800 } 835 }; 836 837 838 #define BOGUS_P1 0xE1 839 #define BOGUS_P2 0xE2 840 841 ULONG not_done_code; 842 843 844 ULONG opcode; 845 ULONG parm_1; 846 ULONG parm_2; 847 848 int i; 849 UCHAR c; 850 851 852 not_done_code = 0; 853 854 opcode = parm[ 1 ]; 855 parm_1 = parm[ 2 ]; 856 parm_2 = parm[ 3 ]; 857 858 859 switch ( opcode ) 860 { 861 862 case LAN_INIT: 863 { 864 865 lan_init( ); 866 printp( "\n\n Interface (Re)Initialized ...\n\n" ); 867 868 break; 869 } 870 871 872 case LAN_BAUD: 873 { 874 875 for ( i = 0; i < (int)(sizeof(baud_rate_setting) / sizeof(baud_rate_setting[0])); i ++ ) 876 { 877 if ( baud_rate_setting[i].rate_code == parm_1 ) 878 { 879 baud_rate_idx = i; 880 *P_LAN_ACR = baud_rate_setting[i].acr_setting; 881 *P_LAN_CSR = baud_rate_setting[i].csr_setting; 882 printp ( "Baud rate set to %X!\n", baud_rate_setting[i].rate_code ); 883 return( not_done_code ); 884 } 885 } 886 887 printp( "\n\n *** SYNTAX Error - Invalid baudrate (P2)\n\n" ); 888 not_done_code = BOGUS_P2; 889 890 break; 891 } 892 893 894 case LAN_INTR: 895 { 896 897 switch ( parm_1 ) 898 { 899 900 case 0x0D: /* Disable 'RxRDY' Interrupts */ 901 { 902 lan_shadow_imr &= ~UART_IMR_RxRDY; 903 *P_LAN_IMR = lan_shadow_imr; 904 printp( "\n\n Receive Ready Interrupts DISABLED ...\n\n" ); 905 break; 906 } 907 908 case 0x0E: /* Enable 'RxRDY' Interrupts */ 909 { 910 lan_shadow_imr |= UART_IMR_RxRDY; 911 *P_LAN_IMR = lan_shadow_imr; 912 printp( "\n\n Receive Ready Interrupts ENABLED ...\n\n" ); 913 break; 914 } 915 916 default: 917 { 918 printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" ); 919 not_done_code = BOGUS_P2; 920 } 921 } 922 923 break; 924 } 925 926 927 case LAN_XMT: 928 { 929 930 switch ( parm_1 ) 931 { 932 933 case 0x0E: /* Enable Transmission-via-Backplane */ 934 { 935 if ( !(*P_LAN0TR_REG & M_LAN0TR) ) 936 { 937 *P_LAN0TR_REG |= M_LAN0TR; /* 0 -> 1 */ 938 } 939 940 printp( "\n\n Transmit-via-Backplane ENABLED ...\n\n" ); 941 break; 942 } 943 944 case 0x0D: /* Disable Transmission-via-Backplane */ 945 { 946 if ( *P_LAN0TR_REG & M_LAN0TR ) 947 { 948 *P_LAN0TR_REG &= ~M_LAN0TR; /* 1 -> 0 */ 949 } 950 951 printp( "\n\n Transmit-via-Backplane DISABLED ...\n\n" ); 952 break; 953 } 954 955 default: 956 { 957 printp( "\n\n *** SYNTAX Error - Invalid P2 (use D or E)\n\n" ); 958 not_done_code = BOGUS_P2; 959 lan_util_menu( ); 960 } 961 } 962 963 break; 964 } 965 966 967 case LAN_STAT: 968 { 969 970 printp( "\n -- Status --\n\n" ); 971 972 printp( " Baud Rate: %X *\n", baud_rate_setting[ baud_rate_idx ].rate_code ); 973 printp( " Xmt-via-BP: %s *\n", STATUS( XMT_VIA_BP_ENABLED( ) ) ); 974 printp( " RxRdy Intr: %s *\n", STATUS( (lan_shadow_imr & M_UART_ISR_RxRDY) ) ); 975 /*** printp( " TxRdy Intr: %s\n", STATUS( (lan_shadow_imr & M_UART_ISR_TxRDY) ) ); ***/ 976 printp( " Echo: %s *\n\n", STATUS( test_echo ) ); 977 978 printp( " IMR: %02X\n", (ULONG) lan_shadow_imr ); 979 printp( " ISR: %02X\n", (ULONG) *P_LAN_ISR ); 980 printp( " SR: %02X\n\n", (ULONG) *P_LAN_SR ); 981 982 printp( " Input Overflows: %d\n\n", lan_input_queue.overflows ); 983 984 printp( " Tx by Intr: %d\n", tx_by_intr ); 985 printp( " Tx by Poll: %d\n\n", tx_by_poll ); 986 987 printp( " * Can be set or toggled via Utility %2X.\n\n", (ULONG) LAN_UTIL_CODE ); 988 989 break; 990 } 991 992 993 case LAN_IN: 994 { 995 996 switch ( parm_1 ) 997 { 998 999 case 0x0C: /* Clear and Reset Queue */ 1000 { 1001 lan_init_queue( &lan_input_queue ); 1002 printp( "\n\n Queue CLEARED/RESET ...\n\n" ); 1003 break; 1004 } 1005 1006 case 0x0D: /* Display Queue */ 1007 { 1008 printp( "\n -- Input Queue --\n" ); 1009 printp( "\n Head Index: %8X Tail Index: %8X\n\n ", 1010 (ULONG) lan_input_queue.head_index, (ULONG) lan_input_queue.tail_index ); 1011 1012 for ( i = 0; i < MAX_RS232_CHARS; ++i ) 1013 { 1014 printp( " %02X", (ULONG) lan_input_queue.buf[ i ] ); 1015 1016 if ( 15 == (i % 16) ) 1017 { 1018 int j; 1019 1020 printp ( " " ); 1021 for ( j = i - 15; j <= i; j++ ) 1022 { 1023 if ( lan_input_queue.buf[ j ] >= ' ' && 1024 lan_input_queue.buf[ j ] < 127 ) 1025 printp ( "%c", lan_input_queue.buf[ j ] ); 1026 else 1027 printp ( "." ); 1028 } 1029 printp( "\n " ); 1030 } 1031 1032 else if ( 7 == (i % 8) ) 1033 { 1034 printp( " " ); 1035 } 1036 1037 } 1038 1039 printp( "\n" ); 1040 1041 break; 1042 } 1043 1044 case 0x0F: /* Fetch next character in Queue */ 1045 { 1046 c = lan_next_queue_char( &lan_input_queue ); 1047 1048 if ( c ) 1049 { 1050 printp( "\n\n Next Character: " ); 1051 if ( 0x21 <= c && c <= 0x7F ) 1052 { 1053 printp( "%c\n\n", (ULONG) c ); 1054 } 1055 1056 else if ( 0x20 == ((UCHAR) c) ) 1057 { 1058 printp( "<space>\n\n" ); 1059 } 1060 1061 else 1062 { 1063 printp( "%02X\n\n", (ULONG) c ); 1064 } 1065 } 1066 1067 else 1068 { 1069 printp( "\n\n Input Queue EMPTY ...\n\n" ); 1070 } 1071 1072 break; 1073 } 1074 1075 default: 1076 { 1077 printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" ); 1078 not_done_code = BOGUS_P2; 1079 break; 1080 } 1081 } 1082 1083 break; 1084 } 1085 1086 1087 case LAN_OUT: 1088 { 1089 1090 switch ( parm_1 ) 1091 { 1092 1093 case 0x0C: /* Clear and Reset Queue */ 1094 { 1095 lan_init_queue( &lan_output_queue ); 1096 printp( "\n\n Queue CLEARED/RESET ...\n\n" ); 1097 break; 1098 } 1099 1100 case 0x0D: /* Display Queue */ 1101 { 1102 printp( "\n -- Output Queue --\n" ); 1103 printp( "\n Head Index: %8X Tail Index: %8X\n\n ", 1104 (ULONG) lan_output_queue.head_index, (ULONG) lan_output_queue.tail_index ); 1105 1106 for ( i = 0; i < MAX_RS232_CHARS; ++i ) 1107 { 1108 printp( " %02X", (ULONG) lan_output_queue.buf[ i ] ); 1109 1110 if ( 15 == (i % 16) ) 1111 { 1112 int j; 1113 1114 printp ( " " ); 1115 for ( j = i - 15; j <= i; j++ ) 1116 { 1117 if ( lan_output_queue.buf[ j ] >= ' ' && 1118 lan_output_queue.buf[ j ] < 127 ) 1119 printp ( "%c", lan_output_queue.buf[ j ] ); 1120 else 1121 printp ( "." ); 1122 } 1123 printp( "\n " ); 1124 } 1125 1126 else if ( 7 == (i % 8) ) 1127 { 1128 printp( " " ); 1129 } 1130 1131 } 1132 1133 printp( "\n" ); 1134 1135 break; 1136 } 1137 1138 case 0x0F: /* Fetch next character in Queue */ 1139 { 1140 c = lan_next_queue_char( &lan_output_queue ); 1141 1142 if ( c ) 1143 { 1144 printp( "\n\n Next Character: " ); 1145 if ( 0x21 <= c && c <= 0x7F ) 1146 { 1147 printp( "%c\n\n", (ULONG) c ); 1148 } 1149 1150 else if ( 0x20 == c ) 1151 { 1152 printp( "<space>\n\n" ); 1153 } 1154 1155 else 1156 { 1157 printp( "%02X\n\n", (ULONG) c ); 1158 } 1159 } 1160 1161 else 1162 { 1163 printp( "\n\n Input Queue EMPTY ...\n\n" ); 1164 } 1165 1166 break; 1167 } 1168 1169 default: 1170 { 1171 printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" ); 1172 not_done_code = BOGUS_P2; 1173 break; 1174 } 1175 } 1176 1177 break; 1178 } 1179 1180 1181 case LAN_ECHO: 1182 { 1183 1184 switch ( parm_1 ) 1185 { 1186 1187 case 0x0E: 1188 { 1189 test_echo = ENABLED; 1190 printp( "\n\n Test echo ENABLED ...\n\n" ); 1191 break; 1192 } 1193 1194 case 0x0D: 1195 { 1196 test_echo = DISABLED; 1197 printp( "\n\n Test echo DISABLED ...\n\n" ); 1198 break; 1199 } 1200 1201 default: 1202 { 1203 printp( "\n\n *** SYNTAX Error - Invalid P2 ...\n\n" ); 1204 not_done_code = BOGUS_P2; 1205 break; 1206 } 1207 } 1208 1209 break; 1210 } 1211 1212 1213 case LAN_PUTC: 1214 { 1215 1216 if ( 0x20 < parm_1 && parm_1 < 0x7F ) 1217 { 1218 if ( lan_put_char( (UCHAR) parm_1 ) ) 1219 { 1220 printp( "\n\n *** 'lan_put_char' Error ...\n" ); 1221 } 1222 1223 else 1224 { 1225 printp( "\n\n O.K. ...\n" ); 1226 } 1227 1228 } 1229 1230 else 1231 { 1232 printp( "\n\n *** Error - character must be in the 0x21-0x7E range ...\n" ); 1233 not_done_code = BOGUS_P2; 1234 } 1235 1236 break; 1237 } 1238 1239 /*** 1240 case LAN_WPM: 1241 { 1242 1243 if ( write_to_protected_mem( (void *) parm_1, (unsigned short) parm_2 ) ) 1244 { 1245 printp( "\n Write to protected memory FAILED ...\n" ); 1246 } 1247 1248 break; 1249 } 1250 ***/ 1251 1252 case 0: /* no argument -- print menu */ 1253 { 1254 lan_util_menu( ); 1255 break; 1256 } 1257 1258 1259 default: 1260 { 1261 parm_2 = 0; /* to supress compiler warning with 'LAN_WPM' case disabled */ 1262 1263 printp( "\n\n *** SYNTAX Error - Invalid P1 ...\n\n" ); 1264 not_done_code = BOGUS_P1; 1265 break; 1266 } 1267 1268 1269 } /* End of 'switch ( opcode )'. */ 1270 1271 1272 return( not_done_code ); 1273 } 1274 /* end of 'lan_util' 1275 *===========================================================================*/ 1276 1277 1278 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%* 1279 * * 1280 * Local Module Functions * 1281 * * 1282 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ 1283 1284 /*----------------------------------------------------------------------------- 1285 * 1286 * FUNCTION NAME: lan_reset 1287 * 1288 * DESCRIPTION: Resets the LAN UART by strobing the 'RST_LAN_UART' bit in the 1289 * Shared Control 1 area. 1290 * 1291 * 1 _| ______ 1292 * | | | 1293 * Bit | | | 1294 * | | | 1295 * 0 _|______| |______ 1296 * |---------------------> t 1297 * 1298 * RETURN VALUE: None. 1299 * 1300 * USED GLOBAL VARIABLES: 1301 * 1302 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 1303 * 1304 * NOTES: H/W configuration requires that a byte in the shared 1305 * control 1 area must be read before being written. 1306 * 1307 *---------------------------------------------------------------------------*/ 1308 1309 static void lan_reset( void ) 1310 1311 { 1312 1313 while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART ) 1314 { 1315 *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART; /* 0 */ 1316 } 1317 1318 while ( !(*P_RST_LAN_UART_REG & M_RST_LAN_UART) ) 1319 { 1320 *P_RST_LAN_UART_REG |= M_RST_LAN_UART; /* 1 */ 1321 } 1322 1323 while ( *P_RST_LAN_UART_REG & M_RST_LAN_UART ) 1324 { 1325 *P_RST_LAN_UART_REG &= ~M_RST_LAN_UART; /* 0 */ 1326 } 1327 1328 } 1329 /* end of 'lan_reset' 1330 *===========================================================================*/ 1331 1332 1333 /*----------------------------------------------------------------------------- 1334 * 1335 * FUNCTION NAME: lan_configure 1336 * 1337 * 1338 * DESCRIPTION: 1339 * 1340 * 1341 * RETURN VALUE: 1342 * 1343 * 1344 * USED GLOBAL VARIABLES: 1345 * 1346 * 1347 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 1348 * 1349 * 1350 * NOTES: 1351 * 1352 * 1353 * 1354 *---------------------------------------------------------------------------*/ 1355 1356 static void lan_configure( void ) 1357 1358 { 1359 1360 *P_LAN_CR = UART_CR_RESET_MR_PTR; /* Points to MR1. */ 1361 *P_LAN_CR = UART_CR_RESET_RVCR; /* Receiver disabled. */ 1362 *P_LAN_CR = UART_CR_RESET_XMTR; /* Transmitter disabled. */ 1363 *P_LAN_CR = UART_CR_RESET_ERROR_STATUS; 1364 *P_LAN_CR = UART_CR_RESET_BRK_CHG_INT; 1365 1366 *P_LAN_MR1 = DEFAULT_LAN_MR1; 1367 *P_LAN_MR2 = DEFAULT_LAN_MR2; 1368 1369 *P_LAN_ACR = DEFAULT_LAN_ACR; 1370 1371 *P_LAN_CSR = UART_CSR_BR_9600; 1372 baud_rate_idx = 2; 1373 1374 *P_LAN_CTUR = DEFAULT_LAN_CTUR; 1375 *P_LAN_CTLR = DEFAULT_LAN_CTLR; 1376 1377 *P_LAN_CR = (UART_CR_START_CNTR_TIMER | UART_CR_ENABLE_XMTR | UART_CR_ENABLE_RCVR); 1378 1379 lan_shadow_imr = UART_IMR_RxRDY; /* Enable only 'RxRDY' interrupt from UART. */ 1380 *P_LAN_IMR = lan_shadow_imr; 1381 1382 tx_by_intr = 0; 1383 tx_by_poll = 0; 1384 1385 return; 1386 } 1387 /* end of 'lan_configure' 1388 *===========================================================================*/ 1389 1390 1391 /*----------------------------------------------------------------------------- 1392 * 1393 * FUNCTION NAME: lan_init_queue 1394 * 1395 * DESCRIPTION: 1396 * 1397 * RETURN VALUE: None. 1398 * 1399 * USED GLOBAL VARIABLES: 1400 * 1401 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 1402 * 1403 * NOTES: 1404 * 1405 *---------------------------------------------------------------------------*/ 1406 1407 static void lan_init_queue( T_RS232_QUEUE *p_queue ) 1408 1409 { 1410 long i; 1411 1412 /* 1413 * We set "head" equal to "tail" implying the queue is empty, 1414 * BUT the "head" and "tail" should each point to valid queue 1415 * positions. 1416 */ 1417 1418 p_queue->head_index = 0; 1419 p_queue->tail_index = 0; 1420 1421 p_queue->overflows = 0; 1422 1423 p_queue->gdb_packet_start = -1; 1424 p_queue->gdb_packet_end = -1; 1425 1426 p_queue->gdb_packet_csum1 = -1; 1427 p_queue->gdb_packet_csum2 = -1; 1428 1429 for ( i = 0; i < MAX_RS232_CHARS; ++i ) 1430 { 1431 p_queue->buf[ i ] = 0; 1432 } 1433 1434 return; 1435 } 1436 /* end of 'lan_init_queue' 1437 *===========================================================================*/ 1438 1439 1440 /*----------------------------------------------------------------------------- 1441 * 1442 * FUNCTION NAME: lan_add_to_queue 1443 * 1444 * 1445 * DESCRIPTION: Adds the specified character to the tail of the 1446 * specified queue. Observes "oldest thrown on floor" 1447 * rule (i.e. the queue is allowed to "wrap" and the 1448 * input character is unconditionally placed at the 1449 * tail of the queue. 1450 * 1451 * 1452 * RETURN VALUE: None. 1453 * 1454 * 1455 * USED GLOBAL VARIABLES: 1456 * 1457 * 1458 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 1459 * 1460 * 1461 * NOTES: 1462 * 1463 * 1464 *---------------------------------------------------------------------------*/ 1465 1466 static void lan_add_to_queue( long c, T_RS232_QUEUE *p_queue ) 1467 1468 { 1469 1470 if ( p_queue ) /* Sanity check. */ 1471 { 1472 1473 if ( c & 0x000000FF ) /* We don't allow NULL characters to be added to a queue. */ 1474 { 1475 /* Insert the new character at the tail of the queue. */ 1476 1477 p_queue->buf[ p_queue->tail_index ] = (UCHAR) (c & 0x000000FF); 1478 1479 /* Increment the tail index. */ 1480 1481 if ( MAX_RS232_CHARS <= ++(p_queue->tail_index) ) 1482 { 1483 p_queue->tail_index = 0; 1484 } 1485 1486 /* Check for wrapping (i.e. overflow). */ 1487 1488 if ( p_queue->head_index == p_queue->tail_index ) 1489 { 1490 /* If the tail has caught up to the head record the overflow . . . */ 1491 1492 ++(p_queue->overflows); 1493 1494 /* . . . then increment the head index. */ 1495 1496 if ( MAX_RS232_CHARS <= ++(p_queue->head_index) ) 1497 { 1498 p_queue->head_index = 0; 1499 } 1500 1501 } 1502 1503 } /* End of 'if ( c & 0x000000FF )'. */ 1504 1505 } /* End of 'if ( p_queue )'. */ 1506 1507 1508 return; 1509 } 1510 /* end of 'lan_add_to_queue' 1511 *===========================================================================*/ 1512 1513 1514 /*----------------------------------------------------------------------------- 1515 * 1516 * FUNCTION NAME: lan_next_queue_char 1517 * 1518 * DESCRIPTION: 1519 * 1520 * RETURN VALUE: 1521 * 1522 * USED GLOBAL VARIABLES: 1523 * 1524 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 1525 * 1526 * NOTES: 1527 * 1528 *---------------------------------------------------------------------------*/ 1529 1530 static UCHAR lan_next_queue_char( T_RS232_QUEUE *p_queue ) 1531 1532 { 1533 UCHAR c; 1534 1535 1536 c = 0; 1537 1538 if ( p_queue ) 1539 { 1540 1541 if ( p_queue->head_index != p_queue->tail_index ) 1542 { 1543 /* Return the 'oldest' character in the queue. */ 1544 1545 c = p_queue->buf[ p_queue->head_index ]; 1546 1547 /* Increment the head index. */ 1548 1549 if ( MAX_RS232_CHARS <= ++(p_queue->head_index) ) 1550 { 1551 p_queue->head_index = 0; 1552 } 1553 1554 } 1555 1556 } /* End of 'if ( p_queue )'. */ 1557 1558 1559 return( c ); 1560 } 1561 1562 /* end of 'lan_next_queue_char' 1563 *===========================================================================*/ 1564 1565 1566 /*----------------------------------------------------------------------------- 1567 * 1568 * FUNCTION NAME: lan_util_menu 1569 * 1570 * DESCRIPTION: Prints out a brief help on the LAN UART control utility. 1571 * 1572 * RETURN VALUE: None. 1573 * 1574 * USED GLOBAL VARIABLES: None. 1575 * 1576 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: None. 1577 * 1578 * NOTES: None. 1579 * 1580 *---------------------------------------------------------------------------*/ 1581 1582 static void lan_util_menu( void ) 1583 1584 { 1585 1586 /* 1587 * Multiply calling printp() below is made due to the limitations 1588 * of printp(), incapable of handling long formatting constants: 1589 */ 1590 1591 printp( "\n -- Options --\n\n" ); 1592 1593 printp( " %2X,'INIT' ............... Reset & (Re)INITIALIZE Interface.\n", (ULONG) LAN_UTIL_CODE ); 1594 printp( " %2X,'BAUD',<rate> ........ Set BAUD Rate.\n", (ULONG) LAN_UTIL_CODE ); 1595 printp( " %2X,'INTR',<mode> ........ Toggle 'RxRDY' Interrupts.\n", (ULONG) LAN_UTIL_CODE ); 1596 printp( " %2X,'XMT',<mode> ......... Toggle TRANSMIT-via-backplane.\n", (ULONG) LAN_UTIL_CODE ); 1597 printp( " %2X,'STAT' ............... Display STATUS.\n", (ULONG) LAN_UTIL_CODE ); 1598 printp( " %2X,'ECHO',<mode> ........ Enable/Disable Test ECHO.\n", (ULONG) LAN_UTIL_CODE ); 1599 printp( " %2X,'IN',<action> ........ Access INPUT Queue.\n", (ULONG) LAN_UTIL_CODE ); 1600 printp( " %2X,'OUT',<action> ....... Access OUTPUT Queue.\n\n", (ULONG) LAN_UTIL_CODE ); 1601 1602 printp( " %2X,'PUTC',<char> ........ Output a Character (i.e. <char>).\n\n", (ULONG) LAN_UTIL_CODE ); 1603 1604 /*** 1605 printp( " %2X,'WPM',address,word ... Write Protected Memory Test.\n\n", (ULONG) LAN_UTIL_CODE ); 1606 ***/ 1607 1608 printp( " <rate>: 4800 <mode>: E - enable <action>: C - clear/reset\n" ); 1609 printp( " 9600 D - disable D - display\n" ); 1610 printp( " 19200 F - fetch next char\n" ); 1611 printp( " 38400\n" ); 1612 } 1613 /* end of 'lan_util_menu' 1614 *===========================================================================*/ 1615 1616 1617 /* Thu Feb 5 17:14:41 EST 1998 CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS...CYGNUS */ 1618 1619 1620 static long get_gdb_input( long c, T_RS232_QUEUE * p_input_q ) 1621 1622 { 1623 1624 /* Now to detect when we've got a gdb packet... */ 1625 1626 if ( '$' == c ) { /* char marks beginning of a packet */ 1627 1628 if ( -1 != p_input_q->gdb_packet_start || 1629 -1 != p_input_q->gdb_packet_end || 1630 -1 != p_input_q->gdb_packet_csum1 || 1631 -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */ 1632 1633 /* NEW: Actually, this probably means that we muffed a packet, 1634 and GDB has already resent it. The thing to do now is to 1635 throw away the one we WERE working on, but immediately start 1636 accepting the new one. Don't NAK, or GDB will have to try 1637 and send it yet a third time! */ 1638 1639 /*NACK_PKT( );*/ /*<ETHERNET>*/ 1640 discard_packet( ); /* throw away old packet */ 1641 lan_add_to_queue ('$', p_input_q); /* put the new "$" back in */ 1642 return 0; 1643 } else { /* match new "$" */ 1644 p_input_q->gdb_packet_start = p_input_q->tail_index; 1645 p_input_q->gdb_packet_end = 1646 p_input_q->gdb_packet_csum1 = 1647 p_input_q->gdb_packet_csum2 = -1; 1648 } 1649 } else if ( '#' == c ) { /* # marks end of packet (except for checksum) */ 1650 1651 if ( -1 == p_input_q->gdb_packet_start || 1652 -1 != p_input_q->gdb_packet_end || 1653 -1 != p_input_q->gdb_packet_csum1 || 1654 -1 != p_input_q->gdb_packet_csum2 ) { /* PROTOCOL ERROR */ 1655 1656 /* Garbled packet. Discard, but do not NAK. */ 1657 1658 /*NACK_PKT( );*/ /*<ETHERNET>*/ 1659 discard_packet( ); 1660 return -1; 1661 } 1662 p_input_q->gdb_packet_end = p_input_q->tail_index; 1663 p_input_q->gdb_packet_csum1 = p_input_q->gdb_packet_csum2 = -1; 1664 1665 } else if ( -1 != p_input_q->gdb_packet_start && 1666 -1 != p_input_q->gdb_packet_end) { 1667 1668 if ( isxdigit( c ) ) { /* char is one of two checksum digits for packet */ 1669 1670 if ( -1 == p_input_q->gdb_packet_csum1 && 1671 LAN_Q_MOD( p_input_q->gdb_packet_end + 1 ) == 1672 p_input_q->tail_index ) { 1673 1674 /* first checksum digit */ 1675 1676 p_input_q->gdb_packet_csum1 = p_input_q->tail_index; 1677 p_input_q->gdb_packet_csum2 = -1; 1678 1679 } else if ( -1 == p_input_q->gdb_packet_csum2 && 1680 LAN_Q_MOD( p_input_q->gdb_packet_end + 2 ) == 1681 p_input_q->tail_index ) { 1682 1683 /* second checksum digit: packet is complete! */ 1684 1685 p_input_q->gdb_packet_csum2 = p_input_q->tail_index; 1686 getpacket(); /* got a packet -- extract it */ 1687 1688 } else { /* probably can't happen (um... three hex digits?) */ 1689 1690 /* PROTOCOL ERROR */ 1691 /* Not sure how this can happen, but ... 1692 discard it, but do not NAK it. */ 1693 /*NACK_PKT( );*/ /*<ETHERNET>*/ 1694 discard_packet( ); 1695 return -1; 1696 } 1697 1698 } else { /* '#' followed by non-hex char */ 1699 1700 /* PROTOCOL ERROR */ 1701 /* Bad packet -- discard but do not NAK */ 1702 /*NACK_PKT( );*/ /*<ETHERNET>*/ 1703 discard_packet( ); 1704 return -1; 1705 } 1706 } 1707 1708 return 0; 1709 } 1710 1711 1712 1713 1714 #ifdef STANDALONE 1715 1716 /* stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone 1717 stand-alone stand-alone 1718 stand-alone Enable stand-alone build, for ease of debugging stand-alone 1719 stand-alone stand-alone 1720 stand-alone stand-alone stand-alone stand-alone stand-alone stand-alone */ 1721 1722 long write_to_protected_mem (addr, word) 1723 void *addr; 1724 unsigned short word; 1725 { 1726 return 0; 1727 } 1728 1729 1730 char dummy_memory[0x4000]; 1731 1732 int main ( void ) 1733 { 1734 long c; 1735 1736 lan_init_queue( &lan_input_queue ); 1737 printf( "Stand-alone EMC 'stub', pid = %d\n", getpid( ) ); 1738 printf( "Start of simulated 'memory': 0x%08x\n", &dummy_memory); 1739 while ( (c = getc( stdin ) ) != EOF ) 1740 { 1741 if ( c == '\\' ) /* escape char */ 1742 break; 1743 1744 lan_add_to_queue( c, &lan_input_queue ); 1745 get_gdb_input (c, &lan_input_queue); 1746 fflush( stdout ); 1747 } 1748 1749 printf( "Goodbye!\n" ); 1750 exit( 0 ); 1751 } 1752 1753 #define SRAM_START ((void *) (&dummy_memory[0] + 0x00000000)) 1754 #define SRAM_END ((void *) (&dummy_memory[0] + 0x00000400)) 1755 1756 #define RO_AREA_START ((void *) (&dummy_memory[0] + 0x00000100)) 1757 #define RO_AREA_END ((void *) (&dummy_memory[0] + 0x00000300)) 1758 1759 #define NVD_START ((void *) (&dummy_memory[0] + 0x00003000)) 1760 #define NVD_END ((void *) (&dummy_memory[0] + 0x00003100)) 1761 1762 #else /* normal stub (not stand-alone) */ 1763 1764 #define SRAM_START ((void *) 0x00000000) 1765 #define SRAM_END ((void *) 0x00400000) 1766 1767 #define RO_AREA_START ((void *) 0x00100000) 1768 #define RO_AREA_END ((void *) 0x00300000) 1769 1770 #define NVD_START ((void *) 0x03000000) 1771 #define NVD_END ((void *) 0x03100000) 1772 1773 #endif /* STANDALONE */ 1774 1775 1776 1777 1778 /* gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb 1779 gdb gdb 1780 gdb Here begins the gdb stub section. gdb 1781 gdb The following functions were added by Cygnus, gdb 1782 gdb to make this thing act like a gdb stub. gdb 1783 gdb gdb 1784 gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb gdb */ 1785 1786 1787 /* ------------------- global defines and data decl's -------------------- */ 1788 1789 #define hexchars "0123456789abcdef" 1790 1791 /* there are 180 bytes of registers on a 68020 w/68881 */ 1792 /* many of the fpa registers are 12 byte (96 bit) registers */ 1793 #define NUMREGBYTES 180 1794 #define NUMREGS 29 1795 #define REGISTER_BYTE(regno) regno 1796 1797 enum regnames { D0, D1, D2, D3, D4, D5, D6, D7, 1798 A0, A1, A2, A3, A4, A5, A6, A7, 1799 PS, PC, 1800 FP0, FP1, 1801 FP2, FP3, 1802 FP4, FP5, 1803 FP6, FP7, 1804 FPCONTROL, FPSTATUS, FPIADDR 1805 }; 1806 1807 unsigned long registers[NUMREGBYTES/4]; 1808 1809 static long remote_debug; 1810 1811 #define BUFMAX MAX_IO_BUF_SIZE 1812 static char inbuffer[BUFMAX], outbuffer[BUFMAX]; 1813 static char spare_buffer[BUFMAX]; 1814 1815 1816 struct stub_trace_frame 1817 { 1818 int valid; 1819 unsigned long frame_id; 1820 unsigned long tdp_id; 1821 FRAME_DEF *frame_data; 1822 COLLECTION_FORMAT_DEF *format; 1823 unsigned long traceregs[NUMREGBYTES/4]; 1824 unsigned char *stack_data; 1825 unsigned char *memrange_data; 1826 } curframe; 1827 1828 /* ------------------- function prototypes -------------------- */ 1829 1830 void handle_request ( char * ); 1831 1832 /* ------------------- Implementation -------------------- */ 1833 1834 static void 1835 discard_packet( void ) 1836 { 1837 lan_input_queue.head_index = lan_input_queue.tail_index; 1838 1839 lan_input_queue.gdb_packet_start = 1840 lan_input_queue.gdb_packet_end = 1841 lan_input_queue.gdb_packet_csum1 = 1842 lan_input_queue.gdb_packet_csum2 = -1; 1843 } 1844 1845 /* Utility function: convert an ASCII isxdigit to a hex nybble */ 1846 1847 static long 1848 hex( char ch ) 1849 { 1850 if ( (ch >= 'A') && (ch <= 'F') ) 1851 return ch - 'A' + 10; 1852 if ( (ch >= 'a') && (ch <= 'f') ) 1853 return ch - 'a' + 10; 1854 if ( (ch >= '0') && (ch <= '9') ) 1855 return ch - '0'; 1856 return -1; 1857 } 1858 1859 static void 1860 getpacket( void ) 1861 { 1862 unsigned char our_checksum, their_checksum; 1863 char *copy = inbuffer; 1864 unsigned char c; 1865 1866 our_checksum = 0; 1867 1868 /* first find the '$' */ 1869 while ((c = lan_next_queue_char ( &lan_input_queue )) != '$') 1870 if (c == 0) /* ??? Protocol error? (paranoia) */ 1871 { 1872 /* PROTOCOL ERROR (missing '$') */ 1873 /*NACK_PKT( );*/ /*<ETHERNET>*/ 1874 return; 1875 } 1876 1877 /* Now copy the message (up to the '#') */ 1878 for (c = lan_next_queue_char ( &lan_input_queue ); /* skip the '$' */ 1879 c != 0 && c != '#'; /* stop at the '#' */ 1880 c = lan_next_queue_char ( &lan_input_queue )) 1881 { 1882 *copy++ = c; 1883 our_checksum += c; 1884 } 1885 *copy++ = '\0'; /* terminate the copy */ 1886 1887 if (c == 0) /* ??? Protocol error? (paranoia) */ 1888 { 1889 /* PROTOCOL ERROR (missing '#') */ 1890 /*NACK_PKT( );*/ /*<ETHERNET>*/ 1891 return; 1892 } 1893 their_checksum = hex( lan_next_queue_char ( &lan_input_queue ) ) << 4; 1894 their_checksum += hex( lan_next_queue_char ( &lan_input_queue ) ); 1895 1896 /* Now reset the queue packet-recognition bits */ 1897 discard_packet( ); 1898 1899 if ( remote_debug || 1900 our_checksum == their_checksum ) 1901 { 1902 ACK_PKT( ); /* good packet */ 1903 /* Parse and process the packet */ 1904 handle_request( inbuffer ); 1905 } 1906 else 1907 /* PROTOCOL ERROR (bad check sum) */ 1908 NACK_PKT( ); 1909 } 1910 1911 /* EMC will provide a better implementation 1912 (perhaps just of LAN_PUT_CHAR) that does not block. 1913 For now, this works. */ 1914 1915 1916 static void 1917 putpacket( char *str ) 1918 { 1919 unsigned char checksum; 1920 1921 /* '$'<packet>'#'<checksum> */ 1922 1923 if ( VIA_ETHERNET == gdb_host_comm ) 1924 { 1925 char *p_out; 1926 long length; 1927 1928 p_out = eth_outbuffer; 1929 length = 0; 1930 1931 1932 if ( YES == gdb_cat_ack ) 1933 { 1934 *p_out++ = '+'; 1935 ++length; 1936 } 1937 1938 gdb_cat_ack = NO; 1939 1940 1941 *p_out++ = '$'; 1942 ++length; 1943 1944 checksum = 0; 1945 1946 while ( *str ) 1947 { 1948 *p_out++ = *str; 1949 ++length; 1950 checksum += *str++; 1951 } 1952 1953 *p_out++ = '#'; 1954 *p_out++ = hexchars[checksum >> 4]; 1955 *p_out = hexchars[checksum % 16]; 1956 length += 3; 1957 1958 eth_to_gdb( (UCHAR *) eth_outbuffer, length ); 1959 } 1960 1961 else 1962 { 1963 1964 /* via RS-232 */ 1965 do { 1966 LAN_PUT_CHAR( '$' ); 1967 checksum = 0; 1968 1969 while ( *str ) 1970 { 1971 LAN_PUT_CHAR( *str ); 1972 checksum += *str++; 1973 } 1974 1975 LAN_PUT_CHAR( '#' ); 1976 LAN_PUT_CHAR( hexchars[checksum >> 4] ); 1977 LAN_PUT_CHAR( hexchars[checksum % 16] ); 1978 } while ( 0 /* get_debug_char( ) != '+' */ ); 1979 /* XXX FIXME: not waiting for the ack. */ 1980 1981 } 1982 1983 } 1984 1985 1986 /*----------------------------------------------------------------------------- 1987 * 1988 * FUNCTION NAME: gdb_get_eth_input 1989 * 1990 * 1991 * DESCRIPTION: 1992 * 1993 * 1994 * RETURN VALUE: None. 1995 * 1996 * 1997 * USED GLOBAL VARIABLES: 1998 * 1999 * 2000 * AFFECTED GLOBAL VARIABLES/SIDE EFFECTS: 2001 * 2002 * 2003 * NOTES: 2004 * 2005 * 2006 *---------------------------------------------------------------------------*/ 2007 2008 void gdb_get_eth_input( unsigned char *buf, long length ) 2009 2010 { 2011 2012 gdb_host_comm = VIA_ETHERNET; 2013 2014 for ( ; 0 < length; ++buf, --length) 2015 { 2016 2017 if ( *buf == CONTROL_C ) 2018 { 2019 /* can't stop the target, but we can tell gdb to stop waiting... */ 2020 discard_packet( ); 2021 putpacket( "S03" ); /* send back SIGINT to the debugger */ 2022 } 2023 2024 else 2025 { 2026 lan_add_to_queue( (long) *buf, &lan_input_queue ); 2027 get_gdb_input( (long) *buf, &lan_input_queue ); 2028 } 2029 2030 } 2031 2032 2033 return; 2034 } 2035 /* end of 'gdb_get_eth_input' 2036 *===========================================================================*/ 2037 2038 2039 2040 2041 /* STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT STDOUT 2042 Stuff pertaining to simulating stdout by sending chars to gdb to be echoed. 2043 2044 Dear reader: 2045 This code is based on the premise that if GDB receives a packet 2046 from the stub that begins with the character CAPITAL-OH, GDB will 2047 echo the rest of the packet to GDB's console / stdout. This gives 2048 the stub a way to send a message directly to the user. In practice, 2049 (as currently implemented), GDB will only accept such a packet when 2050 it believes the target to be running (ie. when you say STEP or 2051 CONTINUE); at other times it does not expect it. This will probably 2052 change as a side effect of the "asynchronous" behavior. 2053 2054 Functions: gdb_putchar(char ch) 2055 gdb_write(char *str, int len) 2056 gdb_puts(char *str) 2057 gdb_error(char *format, char *parm) 2058 */ 2059 2060 #if 0 /* avoid compiler warning while this is not used */ 2061 2062 /* Function: gdb_putchar(int) 2063 Make gdb write a char to stdout. 2064 Returns: the char */ 2065 2066 static int 2067 gdb_putchar( long ch ) 2068 { 2069 char buf[4]; 2070 2071 buf[0] = 'O'; 2072 buf[1] = hexchars[ch >> 4]; 2073 buf[2] = hexchars[ch & 0x0F]; 2074 buf[3] = 0; 2075 putpacket( buf ); 2076 return ch; 2077 } 2078 #endif 2079 2080 /* Function: gdb_write(char *, int) 2081 Make gdb write n bytes to stdout (not assumed to be null-terminated). 2082 Returns: number of bytes written */ 2083 2084 static int 2085 gdb_write( char *data, long len ) 2086 { 2087 char *buf, *cpy; 2088 long i; 2089 2090 buf = outbuffer; 2091 buf[0] = 'O'; 2092 i = 0; 2093 while ( i < len ) 2094 { 2095 for ( cpy = buf+1; 2096 i < len && cpy < buf + BUFMAX - 3; 2097 i++ ) 2098 { 2099 *cpy++ = hexchars[data[i] >> 4]; 2100 *cpy++ = hexchars[data[i] & 0x0F]; 2101 } 2102 *cpy = 0; 2103 putpacket( buf ); 2104 } 2105 return len; 2106 } 2107 2108 /* Function: gdb_puts(char *) 2109 Make gdb write a null-terminated string to stdout. 2110 Returns: the length of the string */ 2111 2112 static int 2113 gdb_puts( char *str ) 2114 { 2115 return gdb_write( str, strlen( str ) ); 2116 } 2117 2118 /* Function: gdb_error(char *, char *) 2119 Send an error message to gdb's stdout. 2120 First string may have 1 (one) optional "%s" in it, which 2121 will cause the optional second string to be inserted. */ 2122 2123 #if 0 2124 static void 2125 gdb_error( char *format, char *parm ) 2126 { 2127 static char buf[400]; 2128 char *cpy; 2129 long len; 2130 2131 if ( remote_debug ) 2132 { 2133 if ( format && *format ) 2134 len = strlen( format ); 2135 else 2136 return; /* empty input */ 2137 2138 if ( parm && *parm ) 2139 len += strlen( parm ); 2140 2141 for ( cpy = buf; *format; ) 2142 { 2143 if ( format[0] == '%' && format[1] == 's' ) /* include 2nd string */ 2144 { 2145 format += 2; /* advance two chars instead of just one */ 2146 while ( parm && *parm ) 2147 *cpy++ = *parm++; 2148 } 2149 else 2150 *cpy++ = *format++; 2151 } 2152 *cpy = '\0'; 2153 gdb_puts( buf ); 2154 } 2155 } 2156 #endif 2157 2158 static void gdb_note (char *, int); 2159 static int error_ret (int, char *, int); 2160 2161 static unsigned long 2162 elinum_to_index (unsigned long elinum) 2163 { 2164 if ((elinum & 0xf0) == 0xd0) 2165 return (elinum & 0x0f); 2166 else if ((elinum & 0xf0) == 0xa0) 2167 return (elinum & 0x0f) + 8; 2168 else 2169 return -1; 2170 } 2171 2172 static long 2173 index_to_elinum (unsigned long index) 2174 { 2175 if (index <= 7) 2176 return index + 0xd0; 2177 else if (index <= 15) 2178 return (index - 8) + 0xa0; 2179 else 2180 return -1; 2181 } 2182 2183 2184 /* 2185 READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM 2186 2187 The following code pertains to reading memory from the target. 2188 Some sort of exception handling should be added to make it safe. 2189 2190 READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM READMEM 2191 2192 Safe Memory Access: 2193 2194 All reads and writes into the application's memory will pass thru 2195 get_uchar() or set_uchar(), which check whether accessing their 2196 argument is legal before actual access (thus avoiding a bus error). 2197 2198 */ 2199 2200 enum { SUCCESS = 0, FAIL = -1 }; 2201 2202 #if 0 2203 static long get_uchar ( const unsigned char * ); 2204 #endif 2205 static long set_uchar ( unsigned char *, unsigned char ); 2206 static long read_access_violation ( const void * ); 2207 static long write_access_violation ( const void * ); 2208 static long read_access_range(const void *, long); 2209 static DTC_RESPONSE find_memory(unsigned char *,long,unsigned char **,long *); 2210 2211 static int 2212 dtc_error_ret (int ret, char *src, DTC_RESPONSE code) 2213 { 2214 if (src) 2215 sprintp (spare_buffer, 2216 "'%s' returned DTC error '%s'.\n", src, get_err_text (code)); 2217 else 2218 sprintp (spare_buffer, "DTC error '%s'.\n", get_err_text (code)); 2219 2220 gdb_puts (spare_buffer); 2221 return ret; 2222 } 2223 2224 2225 #if 0 2226 /* I think this function is unnecessary since the introduction of 2227 adbg_find_memory_addr_in_frame. */ 2228 2229 /* Return the number of expressions in the format associated with a 2230 given trace frame. */ 2231 static int 2232 count_frame_exprs (FRAME_DEF *frame) 2233 { 2234 CFD *format; 2235 T_EXPR *expr; 2236 int num_exprs; 2237 2238 /* Get the format from the frame. */ 2239 get_frame_format_pointer (frame, &format); 2240 2241 /* Walk the linked list of expressions, and count the number of 2242 expressions we find there. */ 2243 num_exprs = 0; 2244 for (expr = format->p_cfd_expr; expr; expr = expr->next) 2245 num_exprs++; 2246 2247 return num_exprs; 2248 } 2249 #endif 2250 2251 #if 0 2252 /* Function: get_frame_addr 2253 * 2254 * Description: If the input memory address was collected in the 2255 * current trace frame, then lookup and return the address 2256 * from within the trace buffer from which the collected byte 2257 * may be retrieved. Else return -1. */ 2258 2259 unsigned char * 2260 get_frame_addr ( const unsigned char *addr ) 2261 { 2262 unsigned char *base, *regs, *stack, *mem; 2263 CFD *dummy; 2264 DTC_RESPONSE ret; 2265 2266 /* first, see if addr is on the saved piece of stack for curframe */ 2267 if (curframe.format->stack_size > 0 && 2268 (base = (unsigned char *) curframe.traceregs[A7]) <= addr && 2269 addr < base + curframe.format->stack_size) 2270 { 2271 gdb_puts("STUB: get_frame_addr: call get_addr_to_frame_regs_stack_mem\n"); 2272 if ((ret = get_addr_to_frame_regs_stack_mem (curframe.frame_data, 2273 &dummy, 2274 (void *) ®s, 2275 (void *) &stack, 2276 (void *) &mem)) 2277 != OK_TARGET_RESPONSE) 2278 return (void *) dtc_error_ret (-1, 2279 "get_addr_to_frame_regs_stack_mem", 2280 ret); 2281 else 2282 return stack + (addr - base); 2283 } 2284 2285 /* Next, try to find addr in the current frame's expression- 2286 collected memory blocks. I'm sure this is at least quadradic in 2287 time. */ 2288 { 2289 int num_exprs = count_frame_exprs (curframe.frame_data); 2290 int expr, block; 2291 2292 /* Try each expression in turn. */ 2293 for (expr = 0; expr < num_exprs; expr++) 2294 { 2295 for (block = 0; ; block++) 2296 { 2297 T_EXPR_DATA *data; 2298 if (adbg_get_expr_data (curframe.frame_data, 2299 'x', expr, block, 2300 &data) 2301 != OK_TARGET_RESPONSE) 2302 break; 2303 else if ((unsigned char *) data->address <= addr 2304 && addr < ((unsigned char *) data->address + data->size)) 2305 { 2306 /* We have found the right block; is it valid data? 2307 Upper-case stamps mean bad data. */ 2308 if ('A' <= data->stamp && data->stamp <= 'Z') 2309 { 2310 gdb_puts("STUB: get_frame_addr: adbg_get_expr_data INVALID\n"); 2311 return (unsigned char *) -1; 2312 } 2313 else 2314 { 2315 if (remote_debug > 1) 2316 { 2317 sprintp(spare_buffer, 2318 "STUB: get_frame_addr: got it [%x,%x)\n", 2319 data->address, data->address + data->size); 2320 gdb_puts(spare_buffer); 2321 } 2322 2323 return (((unsigned char *) &data->data) 2324 + (addr - (unsigned char *) data->address)); 2325 } 2326 } 2327 } 2328 } 2329 } 2330 2331 /* not found, return error */ 2332 return (unsigned char *) -1; 2333 } 2334 2335 /*============================================================*/ 2336 2337 static long get_uchar ( const unsigned char * addr ) 2338 { 2339 unsigned char *frame_addr; 2340 2341 if ( read_access_violation ( addr ) ) 2342 return ( -1 ); /* Access error */ 2343 2344 if (curframe.valid) /* if debugging a trace frame? */ 2345 { 2346 /* If the requested address was collected in the current frame, 2347 * then fetch and return the data from the trace buffer. 2348 */ 2349 if ((frame_addr = get_frame_addr (addr)) != (unsigned char *) -1) 2350 return ( *frame_addr ); 2351 /* If the requested address is in the Code Section, 2352 * let's be magnanimous and read it anyway (else we shall 2353 * not be able to disassemble, find function prologues, etc.) 2354 */ 2355 else if (CS_CODE_START <= (unsigned long) addr && 2356 (unsigned long) addr < CS_CODE_START + CS_CODE_SIZE) 2357 return (*addr); 2358 else 2359 return ( -1 ); /* "Access error" (the data was not collected) */ 2360 } 2361 else 2362 /* Not debugging a trace frame, read the data from live memory. */ 2363 return ( *addr ); /* Meaningful result >= 0 */ 2364 } 2365 #endif 2366 2367 /*============================================================*/ 2368 2369 static long set_uchar ( unsigned char * addr, unsigned char val ) 2370 { 2371 long check_result = write_access_violation ( addr ); 2372 2373 if ( check_result != 0L ) 2374 return ( check_result ); /* Access error */ 2375 2376 return ( *addr = val ); /* Successful writing */ 2377 } 2378 2379 /*============================================================*/ 2380 2381 /* 2382 * Function read_access_violation() below returns TRUE if dereferencing 2383 * its argument for reading would cause a bus error - and FALSE otherwise: 2384 */ 2385 2386 static long read_access_violation ( const void * addr ) 2387 { 2388 return ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) && 2389 ( ( addr < NVD_START ) || ( addr >= NVD_END ) ) ); 2390 } 2391 2392 /*============================================================*/ 2393 2394 /* 2395 * Function write_access_violation() below returns zero if dereferencing 2396 * its argument for writing is safe, -1 on a soft error (the argument 2397 * falls into the write-protected area), -2 on a hard error (the argument 2398 * points to a non-existent memory location). In other words, it returns 2399 * FALSE when no bus error is expected - and an error code otherwise: 2400 */ 2401 2402 static long write_access_violation ( const void * addr ) 2403 { 2404 /* 2405 * The boundaries of the write-protected area have to be received via 2406 * an API provided in the Symmetrix core code. For now, these limits 2407 * are hard-coded: 2408 */ 2409 2410 if ( ( addr >= RO_AREA_START ) && ( addr < RO_AREA_END ) ) 2411 return ( -1 ); /* soft error */ 2412 2413 if ( ( ( addr < SRAM_START ) || ( addr >= SRAM_END ) ) && 2414 ( ( addr < NVD_START ) || ( addr >= NVD_END ) ) ) 2415 return ( -2 ); /* hard error */ 2416 2417 return ( 0 ); 2418 } 2419 2420 2421 /* read_access_range is like read_access_violation, 2422 but returns the number of bytes we can read w/o faulting. 2423 that is, it checks an address range and tells us what portion 2424 (if any) of the prefix is safe to read without a bus error */ 2425 static long 2426 read_access_range(const void *addr, long count) 2427 { 2428 if ((addr >= SRAM_START) && (addr < SRAM_END)) 2429 { 2430 if ((char *)addr + count < (char *)SRAM_END) 2431 return (count); 2432 else 2433 return ((char *)SRAM_END - (char *)addr); 2434 } 2435 else if (((char *)addr >= (char *)NVD_START) && 2436 ((char *)addr < (char *)NVD_END)) 2437 { 2438 if ((char *)addr + count < (char *)NVD_END) 2439 return (count); 2440 else 2441 return ((char *)NVD_END - (char *)addr); 2442 } 2443 else 2444 return (0); 2445 } 2446 2447 /* Convert the memory pointed to by mem into hex, placing result in buf. 2448 Return SUCCESS or FAIL. 2449 If MAY_FAULT is non-zero, then we should return FAIL in response to 2450 a fault; if zero treat a fault like any other fault in the stub. */ 2451 2452 static long 2453 mem2hex(unsigned char *mem, char *buf, long count, long may_fault) 2454 { 2455 long ndx; 2456 long ndx2; 2457 long ch; 2458 long incr; 2459 unsigned char *location; 2460 DTC_RESPONSE status; 2461 2462 if (may_fault) 2463 { 2464 for (ndx = 0, incr = 1; (ndx < count) && (incr > 0); ndx += incr) 2465 { 2466 status = find_memory(mem, count - ndx, &location, &incr); 2467 2468 if (status == OK_TARGET_RESPONSE) 2469 { 2470 if (incr > 0) 2471 { 2472 for (ndx2 = 0; ndx2 < incr; ndx2++) 2473 { 2474 ch = *location++; 2475 *buf++ = hexchars[ch >> 4]; 2476 *buf++ = hexchars[ch & 0xf]; 2477 } 2478 mem += incr; 2479 } 2480 else if (incr <= 0) /* should never happen */ 2481 { 2482 *buf = 0; 2483 return (0); 2484 } 2485 } 2486 else if (status == NOT_FOUND_TARGET_RESPONSE) 2487 { 2488 *buf = 0; 2489 return (ndx); /* return amount copied */ 2490 } 2491 else 2492 { 2493 *buf = 0; 2494 return (0); /* XXX: how do we tell the user the status? */ 2495 } 2496 } 2497 *buf = 0; 2498 return (count); 2499 } 2500 else 2501 { 2502 for (ndx = 0; ndx < count; ndx++) 2503 { 2504 ch = *mem++; 2505 *buf++ = hexchars[ch >> 4]; 2506 *buf++ = hexchars[ch & 0xf]; 2507 } 2508 *buf = 0; 2509 return (count); /* we copied everything */ 2510 } 2511 } 2512 2513 static DTC_RESPONSE 2514 find_memory(unsigned char *mem, long count, 2515 unsigned char **location, long *incr) 2516 { 2517 DTC_RESPONSE retval; 2518 long length; 2519 2520 /* figure out how much of the memory range we can read w/o faulting */ 2521 count = read_access_range(mem, count); 2522 if (count == 0) 2523 return (NOT_FOUND_TARGET_RESPONSE); 2524 2525 if (curframe.valid) 2526 { 2527 unsigned char *mem_block; 2528 unsigned char *mem_addr; 2529 unsigned long mem_size; 2530 unsigned long mem_stamp; 2531 2532 retval = adbg_find_memory_addr_in_frame(curframe.frame_data, mem, 2533 (unsigned long **)&mem_block, 2534 (unsigned long **)&mem_addr, 2535 &mem_size, &mem_stamp); 2536 2537 switch (retval) 2538 { 2539 case OK_TARGET_RESPONSE: 2540 #if 0 2541 printp("FOUND: mem %x block %x addr %x size %d stamp %x\n", 2542 mem, mem_block, mem_addr, mem_size, mem_stamp); 2543 #endif 2544 *location = mem_block + (mem - mem_addr); 2545 length = mem_size - (mem - mem_addr); 2546 2547 if (length < count) 2548 *incr = length; 2549 else 2550 *incr = count; 2551 2552 break; 2553 2554 case NOT_FOUND_TARGET_RESPONSE: 2555 case NEAR_FOUND_TARGET_RESPONSE: 2556 #if 0 2557 printp("NOT FOUND: mem %x, checking code region\n", mem); 2558 #endif 2559 /* check to see if it's in the code region */ 2560 if ((CS_CODE_START <= (long)mem) && 2561 ((long)mem < CS_CODE_START + CS_CODE_SIZE)) 2562 { 2563 /* some or all of the address range is in the code */ 2564 *location = mem; 2565 if ((long)mem + count <= CS_CODE_START + CS_CODE_SIZE) 2566 *incr = count; /* it's totally in the code */ 2567 else 2568 /* how much is in the code? */ 2569 *incr = CS_CODE_START + CS_CODE_SIZE - (long)mem; 2570 #if 0 2571 printp("FOUND in code region: %x\n", mem); 2572 #endif 2573 retval = OK_TARGET_RESPONSE; 2574 } 2575 else 2576 retval = NOT_FOUND_TARGET_RESPONSE; 2577 2578 break; 2579 2580 default: 2581 #if 0 2582 printp("BAD RETURN: %d\n", retval); 2583 #endif 2584 retval = NOT_FOUND_TARGET_RESPONSE; 2585 break; 2586 } 2587 } 2588 else 2589 { 2590 *location = mem; 2591 *incr = count; 2592 retval = OK_TARGET_RESPONSE; 2593 } 2594 2595 return (retval); 2596 } 2597 2598 /* Convert the hex array pointed to by buf into binary to be placed in mem. 2599 Return SUCCESS or FAIL. */ 2600 2601 static long 2602 hex2mem( char *buf, unsigned char *mem, long count, long may_fault ) 2603 { 2604 long i, ch; 2605 2606 for ( i=0; i<count; i++ ) 2607 { 2608 ch = hex( *buf++ ) << 4; 2609 ch = ch + hex( *buf++ ); 2610 if ( may_fault ) 2611 { 2612 ch = set_uchar( mem++, ch ); 2613 if ( ch < 0 ) /* negative return indicates error */ 2614 return FAIL; 2615 } 2616 else 2617 *mem++ = ch; 2618 } 2619 return SUCCESS; 2620 } 2621 2622 /**********************************************/ 2623 /* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ 2624 /* RETURN NUMBER OF CHARS PROCESSED */ 2625 /**********************************************/ 2626 2627 static int 2628 hexToInt( char **ptr, unsigned long *intValue ) 2629 { 2630 long numChars = 0; 2631 long hexValue; 2632 2633 *intValue = 0; 2634 while ( **ptr ) 2635 { 2636 hexValue = hex( **ptr ); 2637 if ( hexValue >=0 ) 2638 { 2639 *intValue = (*intValue << 4) | hexValue; 2640 numChars ++; 2641 } 2642 else 2643 break; 2644 (*ptr)++; 2645 } 2646 return numChars; 2647 } 2648 2649 static volatile long gdb_handling_trap1; 2650 static volatile long gdb_handling_sstrace; 2651 static volatile long gdb_signo; 2652 2653 /* 2654 Here is the "callable" stub entry point. 2655 Call this function with a GDB request as an argument, 2656 and it will service the request and return. 2657 2658 May be further broken up as we go along, with individual requests 2659 broken out as separate functions. 2660 */ 2661 2662 static char * handle_trace_query (char *); 2663 static char * handle_trace_set (char *); 2664 static int handle_format (char **request, CFD *format); 2665 static unsigned long crc32 (unsigned char *buf, int len, unsigned long crc); 2666 static char * crc_query (char *); 2667 static char * handle_test (char *); 2668 2669 void 2670 handle_request( char *request ) 2671 { 2672 #if 0 2673 remote_debug = 2; 2674 #endif 2675 switch( *request++ ) 2676 { 2677 case 'k': /* "kill" */ 2678 curframe.valid = FALSE; 2679 putpacket (""); 2680 break; 2681 case 'D': /* "detach" */ 2682 curframe.valid = FALSE; 2683 putpacket (""); 2684 break; 2685 default: /* Unknown code. Return an empty reply message. */ 2686 putpacket( "" ); /* return empty packet */ 2687 break; 2688 2689 case 'H': /* Set thread for subsequent operations. 2690 Hct... c = 'c' for thread used in step and continue; 2691 t... can be -1 for all threads. 2692 c = 'g' for thread used in other operations. 2693 If zero, pick a thread, any thread. */ 2694 2695 putpacket( "OK" ); 2696 break; 2697 2698 case 'g': /* Read registers. 2699 Each byte of register data is described by 2700 two hex digits. registers are in the 2701 internal order for GDB, and the bytes in a 2702 register are in the same order the machine 2703 uses. */ 2704 { 2705 /* Return the values in (one of) the registers cache(s). 2706 Several situations may pertain: 2707 1) We're synchronous, in which case the "registers" array 2708 should actually be current. 2709 2) We're asynchronous, in which case the "registers" array 2710 holds whatever was cached most recently. 2711 3) We're looking at a trace frame that was collected earlier: 2712 we will return those earlier registers. 2713 */ 2714 2715 /* all registers default to zero */ 2716 memset (outbuffer, '0', NUMREGBYTES); 2717 outbuffer[NUMREGBYTES] = '\0'; 2718 2719 if (curframe.valid) /* debugging a trace frame */ 2720 mem2hex( (unsigned char*) curframe.traceregs, 2721 outbuffer, NUMREGBYTES, 0 ); 2722 else 2723 mem2hex( (unsigned char*) registers, outbuffer, NUMREGBYTES, 0 ); 2724 2725 putpacket( outbuffer ); 2726 } 2727 break; 2728 case 'G': /* Write registers. 2729 Gxxxxxxxx Each byte of register data is described by 2730 two hex digits. */ 2731 if (curframe.valid) /* debugging a trace frame */ 2732 putpacket ("E03"); /* can't write regs into a trace frame! */ 2733 else 2734 { 2735 /* Write the values into the local registers cache... 2736 Note that no actual registers are being changed. */ 2737 2738 hex2mem( request, 2739 (unsigned char *) registers, NUMREGBYTES, 0 ); 2740 putpacket( "OK" ); 2741 } 2742 break; 2743 case 'P': /* Write (single) register. 2744 Pnn=xxxxxxxx register nn gets value xxxxxxxx; 2745 two hex digits for each byte in the register 2746 (target byte order). */ 2747 2748 if (curframe.valid) 2749 putpacket ("E03"); /* can't write regs into a trace frame! */ 2750 else 2751 { 2752 unsigned long regno; 2753 2754 if ( hexToInt( &request, ®no ) && *(request++) == '=' ) 2755 { 2756 if ( regno < NUMREGS ) 2757 { 2758 hexToInt( &request, 2759 (unsigned long *) ®isters[REGISTER_BYTE(regno)]); 2760 2761 putpacket( "OK" ); 2762 } 2763 else 2764 putpacket( "E01" ); /* bad packet or regno */ 2765 } 2766 } 2767 break; 2768 case 'm': /* Read memory. 2769 mAAAAAAAA,LLLL AAAAAAAA is address, LLLL is length. 2770 Reply can be fewer bytes than requested 2771 if able to read only part of the data. */ 2772 { 2773 unsigned long addr, len; 2774 2775 if ( hexToInt( &request, &addr ) && 2776 *(request++) == ',' && 2777 hexToInt( &request, &len ) ) 2778 { 2779 /* better not overwrite outbuffer! */ 2780 if ( len > (BUFMAX / 2) - 5 ) 2781 len = (BUFMAX / 2) - 5; 2782 if (mem2hex((unsigned char *) addr, outbuffer, len, 1) == 0) /* XXX: eventually use returned value */ 2783 putpacket( "E03" ); /* read fault (access denied) */ 2784 else 2785 putpacket( outbuffer ); /* read succeeded */ 2786 } 2787 else 2788 putpacket( "E01" ); /* badly formed read request */ 2789 2790 } 2791 break; 2792 case 'M': /* Write memory. 2793 Maaaaaaaa,llll:xxxx aaaaaaaa is address, llll is length; 2794 xxxx is data to write. */ 2795 2796 { 2797 unsigned long addr, len; 2798 2799 if (curframe.valid) /* can't write memory into a trace frame! */ 2800 putpacket ("E03"); /* "access denied" */ 2801 else /*** if ( write_access_enabled ) ***/ 2802 { 2803 if ( hexToInt( &request, &addr ) && 2804 *(request++) == ',' && 2805 hexToInt( &request, &len ) && 2806 *(request++) == ':' ) 2807 { 2808 if (len == 2 && 2809 addr >= CS_CODE_START && 2810 addr <= LAST_CS_WORD) 2811 { 2812 unsigned long val; 2813 2814 if ( !hexToInt( &request, &val ) || 2815 write_to_protected_mem( (void *)addr, val ) ) 2816 putpacket( "E03" ); /* write fault (access denied) */ 2817 else 2818 putpacket( "OK" ); /* write succeeded */ 2819 } 2820 else 2821 { 2822 if ( hex2mem( request, (unsigned char*) addr, len, 1 ) ) 2823 putpacket( "E03" ); /* write fault (access denied) */ 2824 else 2825 putpacket( "OK" ); /* write succeeded */ 2826 } 2827 } 2828 else 2829 putpacket( "E02" ); /* badly formed write request */ 2830 } 2831 } 2832 break; 2833 case 'c': /* Continue. 2834 cAAAAAAAA AAAAAAAA is address from which to resume. 2835 If omitted, resume at current PC. */ 2836 2837 { 2838 unsigned long addr; 2839 2840 if (curframe.valid) 2841 { 2842 /* Don't continue if debugging a trace frame! */ 2843 gdb_puts ("Error: can't continue!\n"); 2844 putpacket ("S03"); 2845 } 2846 else 2847 { 2848 gdb_signo = 3; 2849 if (isxdigit(request[0])) 2850 { 2851 hexToInt(&request, &addr); 2852 registers[REGISTER_BYTE(PC)] = addr; 2853 } 2854 2855 gdb_handling_trap1 = FALSE; 2856 gdb_handling_sstrace = FALSE; 2857 sss_trace_flag = '\0'; 2858 } 2859 } 2860 break; 2861 case 's': /* Step. 2862 sAAAAAAAA AAAAAAAA is address from which to begin stepping. 2863 If omitted, begin stepping at current PC. */ 2864 { 2865 unsigned long addr; 2866 2867 if (curframe.valid) 2868 { 2869 /* Don't step if debugging a trace frame! */ 2870 gdb_puts ("Error: can't step!\n"); 2871 putpacket ("S03"); 2872 } 2873 else 2874 { 2875 gdb_signo = 3; 2876 if (isxdigit(request[0])) 2877 { 2878 hexToInt(&request, &addr); 2879 registers[REGISTER_BYTE(PC)] = addr; 2880 } 2881 2882 gdb_handling_trap1 = FALSE; 2883 gdb_handling_sstrace = FALSE; 2884 sss_trace_flag = 't'; 2885 } 2886 } 2887 break; 2888 case 'C': /* Continue with signal. 2889 Cxx;AAAAAAAA xx is signal number in hex; 2890 AAAAAAAA is adddress from which to resume. 2891 If ;AAAAAAAA omitted, continue from PC. */ 2892 2893 { 2894 unsigned long addr = 0; 2895 2896 if (!gdb_handling_trap1 || curframe.valid) 2897 { 2898 /* Don't continue if not currently in synchronous mode, 2899 or if currently debugging a trace frame! */ 2900 gdb_puts( "Error: can't continue!\n" ); 2901 putpacket( "S03" ); /* "sigquit" (better idea?) */ 2902 } 2903 else 2904 { 2905 gdb_signo = 3; 2906 if ( isxdigit( *request ) ) 2907 { 2908 hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 ); 2909 request += 2; 2910 if ( *request == ';' && isxdigit( *++request ) ) 2911 { 2912 hexToInt( &request, &addr ); 2913 registers[REGISTER_BYTE(PC)] = addr; 2914 } 2915 } 2916 gdb_handling_trap1 = FALSE; 2917 gdb_handling_sstrace = FALSE; 2918 sss_trace_flag = '\0'; 2919 } 2920 } 2921 break; 2922 case 'S': /* Step with signal. 2923 Sxx;AAAAAAAA xx is signal number in hex; 2924 AAAAAAAA is adddress from which to begin stepping. 2925 If ;AAAAAAAA omitted, begin stepping from PC. */ 2926 { 2927 unsigned long addr = 0; 2928 2929 if (!gdb_handling_trap1 || curframe.valid) 2930 { 2931 /* Don't step if not currently in synchronous mode, 2932 or if currently debugging a trace frame! */ 2933 gdb_puts( "Error: can't step!\n" ); 2934 putpacket( "S03" ); /* "sigquit" (better idea?) */ 2935 } 2936 else 2937 { 2938 gdb_signo = 3; 2939 if ( isxdigit( *request ) ) 2940 { 2941 hex2mem( request, (unsigned char *) &gdb_signo, 2, 0 ); 2942 request += 2; 2943 if ( *request == ';' && isxdigit( *++request ) ) 2944 { 2945 hexToInt( &request, &addr ); 2946 registers[REGISTER_BYTE(PC)] = addr; 2947 } 2948 } 2949 gdb_handling_trap1 = FALSE; 2950 gdb_handling_sstrace = FALSE; 2951 sss_trace_flag = 't'; 2952 } 2953 } 2954 break; 2955 case '?': /* Query the latest reason for stopping. 2956 Should be same reply as was last generated 2957 for step or continue. */ 2958 2959 if ( gdb_signo == 0 ) 2960 gdb_signo = 3; /* default to SIGQUIT */ 2961 outbuffer[ 0 ] = 'S'; 2962 outbuffer[ 1 ] = hexchars[ gdb_signo >> 4 ]; 2963 outbuffer[ 2 ] = hexchars[ gdb_signo & 0xf ]; 2964 outbuffer[ 3 ] = 0; 2965 putpacket( outbuffer ); 2966 break; 2967 2968 case 'd': /* Toggle debug mode 2969 I'm sure we can think of something interesting. */ 2970 2971 remote_debug = !remote_debug; 2972 putpacket( "" ); /* return empty packet */ 2973 break; 2974 2975 case 'q': /* general query */ 2976 switch (*request++) 2977 { 2978 default: 2979 putpacket (""); /* nak a request which we don't handle */ 2980 break; 2981 case 'T': /* trace query */ 2982 putpacket (handle_trace_query (request)); 2983 break; 2984 case 'C': /* crc query (?) */ 2985 if (*request++ == 'R' && 2986 *request++ == 'C' && 2987 *request++ == ':') 2988 putpacket (crc_query (request)); 2989 else 2990 putpacket (""); /* unknown query */ 2991 break; 2992 } 2993 break; 2994 2995 case 'Q': /* general set */ 2996 switch (*request++) 2997 { 2998 default: 2999 putpacket (""); /* nak a request which we don't handle */ 3000 break; 3001 case 'T': /* trace */ 3002 putpacket (handle_trace_set (request)); 3003 break; 3004 } 3005 break; 3006 3007 case 'T': 3008 /* call test function: TAAA,BBB,CCC 3009 A, B, and C are arguments to pass to gdb_c_test. Reply is 3010 "E01" (bad arguments) or "OK" (test function called). */ 3011 putpacket (handle_test (request)); 3012 break; 3013 } 3014 } 3015 3016 static TDP_SETUP_INFO tdp_temp; 3017 static int trace_running; 3018 3019 /* 3020 * Function msgcmp: 3021 * 3022 * If second argument (str) is matched in first argument, 3023 * then advance first argument past end of str and return "SAME" 3024 * else return "DIFFERENT" without changing first argument. 3025 * 3026 * Return: zero for DIFFERENT, non-zero for SUCCESS 3027 */ 3028 3029 static int 3030 msgcmp (char **msgp, char *str) 3031 { 3032 char *next; 3033 3034 if (msgp != 0 && str != 0) /* input validation */ 3035 if ((next = *msgp) != 0) 3036 { 3037 for (; 3038 *next && *str && *next == *str; 3039 next++, str++) 3040 ; 3041 3042 if (*str == 0) /* matched all of str in msg */ 3043 return (int) (*msgp = next); /* advance msg ptr past str */ 3044 } 3045 return 0; /* failure */ 3046 } 3047 3048 static char * 3049 handle_trace_query (char *request) 3050 { 3051 if (msgcmp (&request, "Status")) 3052 { 3053 if (adbg_check_if_active ()) 3054 { 3055 gdb_puts ("Target trace is running.\n"); 3056 return "T1"; 3057 } 3058 else 3059 { 3060 gdb_puts ("Target trace not running.\n"); 3061 trace_running = 0; 3062 return "T0"; 3063 } 3064 } 3065 else /* unknown trace query */ 3066 { 3067 return ""; 3068 } 3069 } 3070 3071 static void 3072 gdb_note (char *fmt, int arg1) 3073 { 3074 if (remote_debug > 1) 3075 { 3076 sprintp (spare_buffer, fmt, arg1); 3077 gdb_puts (spare_buffer); 3078 } 3079 } 3080 3081 static int 3082 error_ret (int ret, char *fmt, int arg1) 3083 { 3084 if (remote_debug > 0) 3085 { 3086 sprintp (spare_buffer, fmt, arg1); 3087 gdb_puts (spare_buffer); 3088 } 3089 return ret; 3090 } 3091 3092 static int 3093 handle_format (char **request, COLLECTION_FORMAT_DEF *format) 3094 { 3095 MEMRANGE_DEF m; 3096 DTC_RESPONSE ret; 3097 int elinum; 3098 unsigned long regnum; 3099 long bytecodes[(MAX_BYTE_CODES + sizeof (struct t_expr_tag))/ 4]; 3100 struct t_expr_tag *t_expr = (struct t_expr_tag *)bytecodes; 3101 3102 if (format->id == 0) 3103 { 3104 if ((ret = get_unused_format_id (&format->id)) != OK_TARGET_RESPONSE) 3105 return dtc_error_ret (-1, "get_unused_format_id", ret); 3106 3107 if (**request == 'R') 3108 { 3109 (*request)++; 3110 hexToInt (request, &format->regs_mask); 3111 } 3112 gdb_note ("STUB: call define_format (id = %d, ", format->id); 3113 gdb_note ("regs_mask = 0x%X);\n", format->regs_mask); 3114 3115 if ((ret = define_format (format)) != OK_TARGET_RESPONSE) 3116 { 3117 sprintp (spare_buffer, 3118 "'define_format': DTC error '%s' for format id %d.\n", 3119 get_err_text (ret), 3120 format->id); 3121 gdb_puts (spare_buffer); 3122 return -1; 3123 } 3124 } 3125 3126 while ((**request == 'M') || (**request == 'X')) 3127 { 3128 switch (**request) 3129 { 3130 case 'M': /* M<regnum>,<offset>,<size> */ 3131 (*request)++; 3132 hexToInt(request, ®num); 3133 3134 if (regnum == 0 || regnum == (unsigned long) -1) 3135 m.typecode = -1; 3136 else if ((elinum = index_to_elinum (regnum)) > 0) 3137 m.typecode = elinum; 3138 else 3139 return error_ret (-1, 3140 "Memrange register %d is not between 0 and 15\n", 3141 regnum); 3142 3143 if (*(*request)++ != ',') 3144 return error_ret (-1,"Malformed memrange (comma #%d missing)\n",1); 3145 hexToInt(request, &m.offset); 3146 if (*(*request)++ != ',') 3147 return error_ret (-1,"Malformed memrange (comma #%d missing)\n",2); 3148 hexToInt(request, &m.size); 3149 3150 gdb_note ("STUB: call add_format_mem_range (typecode = 0x%x, ", 3151 m.typecode); 3152 gdb_note ("offset = 0x%X, ", m.offset); 3153 gdb_note ("size = %d);\n", m.size); 3154 if ((ret = add_format_mem_ranges (format->id, &m)) != 3155 OK_TARGET_RESPONSE) 3156 { 3157 dtc_error_ret (-1, "add_format_mem_ranges", ret); 3158 sprintp (spare_buffer, 3159 "format id %d: memrange (0x%x, 0x%x, 0x%x).\n", 3160 format->id, m.typecode, m.offset, m.size); 3161 gdb_puts (spare_buffer); 3162 return -1; 3163 } 3164 break; 3165 3166 case 'X': /* X<length>,<bytecodes> */ 3167 { 3168 unsigned long length; 3169 3170 (*request)++; 3171 hexToInt(request, &length); 3172 3173 if ((length <= 0) || (length > MAX_BYTE_CODES)) 3174 return error_ret (-1, 3175 "Bytecode expression length (%d) too large\n", 3176 length); 3177 3178 if (*(*request)++ != ',') 3179 return error_ret (-1, 3180 "Malformed bytecode expr (comma#%d missing)\n", 3181 1); 3182 t_expr->next = NULL; 3183 /* subtract one to account for expr[0] in header */ 3184 t_expr->size = sizeof(struct t_expr_tag) + length - 1; 3185 t_expr->expr_size = length; 3186 3187 hex2mem(*request, &t_expr->expr[0], length, 0); 3188 *request += 2 * length; 3189 build_and_add_expression(format->id, t_expr); 3190 } 3191 break; 3192 } 3193 } 3194 return 0; 3195 } 3196 3197 static char * 3198 handle_trace_set (char *request) 3199 { 3200 long n_frame; 3201 unsigned long frameno, tdp, pc, start, stop; 3202 DTC_RESPONSE ret = -1; 3203 static COLLECTION_FORMAT_DEF tempfmt1; 3204 static char enable; 3205 static char retbuf[20]; 3206 3207 if (msgcmp (&request, "init")) 3208 { 3209 gdb_note ("STUB: call clear_trace_state();\n", 0); 3210 curframe.valid = 0; /* all old frames become invalid now */ 3211 if ((ret = clear_trace_state ()) == OK_TARGET_RESPONSE) 3212 return "OK"; 3213 else 3214 { 3215 sprintp (retbuf, "E2%x", ret); 3216 return (char *) dtc_error_ret ((int) &retbuf, 3217 "clear_trace_state", 3218 ret); 3219 } 3220 } 3221 else if (msgcmp (&request, "Start")) 3222 { 3223 trace_running = 1; 3224 curframe.valid = 0; /* all old frames become invalid now */ 3225 gdb_note ("STUB: call start_trace_experiment();\n", 0); 3226 adbg_save_trace_in_nvd (); 3227 if ((ret = start_trace_experiment ()) == OK_TARGET_RESPONSE) 3228 return "OK"; 3229 else 3230 { 3231 sprintp (retbuf, "E2%x", ret); 3232 return (char *) dtc_error_ret ((int) &retbuf, 3233 "start_trace_experiment", 3234 ret); 3235 } 3236 } 3237 else if (msgcmp (&request, "Stop")) 3238 { 3239 trace_running = 0; 3240 if (adbg_check_if_active ()) 3241 { 3242 gdb_note ("STUB: call end_trace_experiment();\n", 0); 3243 if ((ret = end_trace_experiment ()) == OK_TARGET_RESPONSE) 3244 return "OK"; 3245 else 3246 { 3247 sprintp (retbuf, "E2%x", ret); 3248 return (char *) dtc_error_ret ((int) &retbuf, 3249 "end_trace_experiment", 3250 ret); 3251 } 3252 } 3253 else return "OK"; 3254 } 3255 /* "TDP:" (The 'T' was consumed in handle_request.) */ 3256 else if (msgcmp (&request, "DP:")) 3257 { 3258 /* TDP:<id>:<addr>:{D,E}:<stepcount>:<pass_limit>{R[M,X]+}<tdp-format> 3259 {S{R[M,X]+}}<tp-format> 3260 3261 D -- disable tracepoint (illegal from EMC's point of view) 3262 E -- enable tracepoint? 3263 3264 R -- regs format: R<regs-mask> 3265 M -- memory format: M<regnum>,<offset>,<size> 3266 X -- expr format: X<size>,<bytecodes> 3267 S -- fencepost between trap formats and stepping formats. 3268 */ 3269 3270 /* state variable, required for splitting TDP packets. */ 3271 static int doing_step_formats; 3272 3273 /* 3274 * TDP: packets may now be split into multiple packets. 3275 * If a TDP packet is to be continued in another packet, it 3276 * must end in a "-" character. The subsequent continuation 3277 * packet will then begin with a "-" character, between the 3278 * token "TDP:" and the tdp_id field. The ID and address 3279 * will be repeated in each sub-packet. The step_count, 3280 * pass_count, and 'enabled' field must appear in the first 3281 * packet. The boundary between sub-packets may not appear 3282 * between the "S" that denotes the start of stepping "formats", 3283 * and the regs_mask that follows it. The split may also not 3284 * occur in the middle of either a memrange description or a 3285 * bytecode string. -- MVS 3286 */ 3287 3288 if (*request == '-') /* this is a continuation of a 3289 trace definition in progress */ 3290 { 3291 unsigned long temp_id, temp_addr; 3292 3293 request++; 3294 if (!(hexToInt (&request, &temp_id) && 3295 *request++ == ':')) 3296 return "E11"; /* badly formed packet, field 1 */ 3297 3298 if (!(hexToInt (&request, (unsigned long *) &temp_addr) && 3299 *request++ == ':')) 3300 return "E12"; /* badly formed packet, field 2 */ 3301 3302 if (temp_id != tdp_temp.id) 3303 return "E11"; /* something wrong: field 1 doesn't match */ 3304 if (temp_addr != (unsigned long) tdp_temp.addr) 3305 return "E12"; /* something wrong: field 2 doesn't match */ 3306 } 3307 else /* This is a new TDP definition */ 3308 { 3309 memset ((char *) &tdp_temp, 0, sizeof (tdp_temp)); 3310 memset ((char *) &tempfmt1, 0, sizeof (tempfmt1)); 3311 doing_step_formats = FALSE; 3312 3313 if (!(hexToInt (&request, &tdp_temp.id) && 3314 *request++ == ':')) 3315 return "E11"; /* badly formed packet, field 1 */ 3316 3317 if (!(hexToInt (&request, (unsigned long *) &tdp_temp.addr) && 3318 *request++ == ':')) 3319 return "E12"; /* badly formed packet, field 2 */ 3320 3321 if (!(((enable = *request++) == 'D' || enable == 'E') && 3322 *request++ == ':')) 3323 return "E13"; /* badly formed packet, field 3 */ 3324 #if 0 3325 if (enable == 'D') 3326 { 3327 gdb_puts ("Disabling of tracepoints not supported by EMC target\n"); 3328 return "E20"; 3329 } 3330 #endif 3331 if (!(hexToInt (&request, &tdp_temp.stepcount) && 3332 *request++ == ':')) 3333 return "E14"; /* badly formed packet, field 4 */ 3334 3335 if (!hexToInt (&request, &tdp_temp.pass_limit)) 3336 return "E15"; /* badly formed packet, field 5 */ 3337 3338 } 3339 3340 /* Typically, the first group of collection descriptors 3341 refers to the trap collection. There is an "S" token 3342 to act as a fencepost between collection descriptors for 3343 the trap, and those for the single-stepping. 3344 3345 However, when the packet is split up into several packets, 3346 this "S" token may already have been seen in a previous 3347 sub-packet; so we have to remember it in a state variable. */ 3348 3349 if (*request == 'R' || *request == 'M' || *request == 'X') 3350 { 3351 if (handle_format (&request, &tempfmt1)) 3352 return "E16"; 3353 if (doing_step_formats) 3354 tdp_temp.tp_format_p = tempfmt1.id; 3355 else 3356 tdp_temp.tdp_format_p = tempfmt1.id; 3357 } 3358 3359 /* When we see the "S" token, we remember it in a state variable 3360 (in case the packet is split up and continued in another message), 3361 and discard all current state from the collection "format". */ 3362 if (*request == 'S') 3363 { 3364 doing_step_formats = TRUE; 3365 /* discard prev format and start a new one */ 3366 memset ((char *) &tempfmt1, 0, sizeof (tempfmt1)); 3367 request++; 3368 3369 /* Having seen the "S" fencepost, it is now possible that 3370 we will see some more collection descriptors pertaining 3371 to the stepping collection. */ 3372 if (*request == 'R' || *request == 'M' || *request == 'X') 3373 { 3374 if (handle_format (&request, &tempfmt1)) 3375 return "E17"; 3376 /* new format ID is tp_format */ 3377 tdp_temp.tp_format_p = tempfmt1.id; 3378 } 3379 } 3380 3381 if (*request == '-') /* this TDP definition will be continued. */ 3382 sprintp (retbuf, "OK"); 3383 else if (enable == 'E') /* end of TDP definition: pass to ADBG (if enabled!) */ 3384 { 3385 gdb_note ("STUB: call define_tdp (id %d, ", tdp_temp.id); 3386 gdb_note ("addr 0x%X, ", (int) tdp_temp.addr); 3387 gdb_note ("passc %d, ", tdp_temp.pass_limit); 3388 gdb_note ("stepc %d, ", tdp_temp.stepcount); 3389 gdb_note ("TDP fmt #%d, ", tdp_temp.tdp_format_p); 3390 gdb_note ("TP fmt #%d);\n", tdp_temp.tp_format_p); 3391 3392 ret = define_tdp (tdp_temp.id, &tdp_temp, 0); 3393 3394 if (ret == OK_TARGET_RESPONSE) 3395 { 3396 sprintp (retbuf, "OK"); 3397 } 3398 else 3399 { 3400 sprintp (spare_buffer, 3401 "'define_tdp' returned DTC error '%s' for tracepoint %d.\n", 3402 get_err_text (ret), 3403 tdp_temp.id); 3404 gdb_puts (spare_buffer); 3405 sprintp (retbuf, "E2%x", ret); 3406 } 3407 /* Redundant, but let's try to make sure this state gets discarded. */ 3408 { 3409 memset ((char *) &tdp_temp, 0, sizeof (tdp_temp)); 3410 memset ((char *) &tempfmt1, 0, sizeof (tempfmt1)); 3411 } 3412 } 3413 else /* ADBG_DTC does not support disabled tracepoints -- ignore it. */ 3414 gdb_note ("STUB: ignoring disabled tracepoint %d.\n", tdp_temp.id); 3415 3416 return retbuf; 3417 } 3418 else if (msgcmp (&request, "Frame:")) 3419 { 3420 ret = OK_TARGET_RESPONSE; 3421 3422 if (msgcmp (&request, "pc:")) 3423 { 3424 if (!hexToInt (&request, &pc)) 3425 return "E10"; /* badly formed packet */ 3426 n_frame = curframe.valid ? curframe.frame_id + 1 : 0; 3427 gdb_note ("STUB: call fetch_trace_frame_pc (id %d, ", n_frame); 3428 gdb_note ("pc 0x%X);\n", pc); 3429 ret = fetch_trace_frame_with_pc (&n_frame, 3430 (void *) pc, 3431 &curframe.format, 3432 &curframe.frame_data); 3433 } 3434 else if (msgcmp (&request, "tdp:")) 3435 { 3436 if (!hexToInt (&request, &tdp)) 3437 return "E10"; /* badly formed packet */ 3438 n_frame = curframe.valid ? curframe.frame_id + 1: 0; 3439 gdb_note ("STUB: call fetch_trace_frame_tdp (id %d, ", n_frame); 3440 gdb_note ("tdp 0x%X);\n", tdp); 3441 ret = fetch_trace_frame_with_tdp (&n_frame, 3442 tdp, 3443 &curframe.format, 3444 &curframe.frame_data); 3445 } 3446 else if (msgcmp (&request, "range:")) 3447 { 3448 if (!(hexToInt (&request, &start) && 3449 *request++ == ':')) 3450 return "E11"; /* badly formed packet, field 1 */ 3451 else if (!hexToInt (&request, &stop)) 3452 return "E12"; /* badly formed packet, field 2 */ 3453 n_frame = curframe.valid ? curframe.frame_id + 1: 0; 3454 gdb_note ("STUB: call fetch_trace_frame_range (id %d, ", n_frame); 3455 gdb_note ("start 0x%X, ", start); 3456 gdb_note ("stop 0x%X);\n", stop); 3457 ret = fetch_trace_frame_with_pc_in_range (&n_frame, 3458 (void *) start, 3459 (void *) stop, 3460 &curframe.format, 3461 &curframe.frame_data); 3462 } 3463 else if (msgcmp (&request, "outside:")) 3464 { 3465 if (!(hexToInt (&request, &start) && 3466 *request++ == ':')) 3467 return "E11"; /* badly formed packet, field 1 */ 3468 else if (!hexToInt (&request, &stop)) 3469 return "E12"; /* badly formed packet, field 2 */ 3470 n_frame = curframe.valid ? curframe.frame_id + 1: 0; 3471 gdb_note ("STUB: call fetch_trace_frame_outside (id %d, ", n_frame); 3472 gdb_note ("start 0x%X, ", start); 3473 gdb_note ("stop 0x%X);\n", stop); 3474 ret = fetch_trace_frame_with_pc_outside (&n_frame, 3475 (void *) start, 3476 (void *) stop, 3477 &curframe.format, 3478 &curframe.frame_data); 3479 } 3480 else /* simple TFind by frame number: */ 3481 { 3482 if (!hexToInt (&request, &frameno)) 3483 return "E10"; /* badly formed packet */ 3484 if (frameno != (unsigned long) -1) 3485 { 3486 gdb_note ("STUB: call fetch_trace_frame (id %d);\n", frameno); 3487 ret = fetch_trace_frame (n_frame = frameno, 3488 &curframe.format, 3489 &curframe.frame_data); 3490 #if 0 3491 printp("STUB: fetch_trace_frame: return %d\n", ret); 3492 #endif 3493 } 3494 else /* discard any trace frame, debug "the real world" */ 3495 { 3496 if (curframe.valid) 3497 gdb_note ("STUB: discard current trace frame #%d.\n", 3498 curframe.frame_id); 3499 curframe.valid = 0; 3500 return "OK"; 3501 } 3502 } 3503 if (ret == OK_TARGET_RESPONSE) /* fetch_trace_frame succeeded */ 3504 { /* setup for debugging the trace frame */ 3505 curframe.valid = 1; 3506 curframe.frame_id = n_frame; 3507 curframe.tdp_id = curframe.frame_data->id; 3508 3509 memset ((char *) &curframe.traceregs, 0, 3510 sizeof (curframe.traceregs)); 3511 curframe.traceregs[PC] = (unsigned long) 3512 curframe.frame_data->program_counter; 3513 3514 if (curframe.format) 3515 { 3516 unsigned long regs_mask = curframe.format->regs_mask; 3517 unsigned long *regs, *stack, *mem; 3518 unsigned long regno, index = 0; 3519 CFD *dummy; 3520 3521 if ((ret = get_addr_to_frame_regs_stack_mem 3522 (curframe.frame_data, &dummy, ®s, &stack, &mem)) 3523 != OK_TARGET_RESPONSE) 3524 { 3525 curframe.valid = 0; 3526 sprintp (retbuf, "E2%x", ret); 3527 return (char *) 3528 dtc_error_ret ((int) &retbuf, 3529 "get_addr_to_frame_regs_stack_mem", 3530 ret); 3531 } 3532 3533 if (remote_debug > 1) 3534 { /* echo what we've found to gdb console */ 3535 sprintp (spare_buffer, 3536 "STUB: Found frame %d, TDP %d, format %d (%s):\n", 3537 curframe.frame_id, 3538 curframe.tdp_id & 0x7fffffff, 3539 curframe.format->id, 3540 curframe.tdp_id & 0x80000000 ? 3541 "trap frame" : "stepping frame"); 3542 gdb_puts (spare_buffer); 3543 } 3544 /* copy trace frame regs into stub's data format */ 3545 for (regno = 0, index = 0; 3546 regno < 16; 3547 regno++, regs_mask >>= 1) 3548 if (regs_mask & 1) /* got a collected register */ 3549 { 3550 curframe.traceregs[regno] = regs[index++]; 3551 if (remote_debug > 1) 3552 { 3553 sprintp (spare_buffer, 3554 " Collected 0x%08x for register %d.\n", 3555 curframe.traceregs[regno], regno); 3556 gdb_puts (spare_buffer); 3557 } 3558 } 3559 if (remote_debug > 1) 3560 { 3561 long midx, ridx, len; 3562 MEMRANGE_DEF *mrange; 3563 unsigned char *data, *base; 3564 3565 if (curframe.format->stack_size > 0) 3566 { 3567 len = curframe.format->stack_size; 3568 sprintp (spare_buffer, 3569 " Collected %d bytes of stack at 0x%x:\n", 3570 len, curframe.traceregs[A7]); 3571 gdb_puts (spare_buffer); 3572 3573 /* print stack data, but stay under msg len */ 3574 if (len >= (NUMREGBYTES/2 - 2)) 3575 len = (NUMREGBYTES/2 - 3); 3576 mem2hex ((unsigned char *) stack, 3577 spare_buffer, len, 0); 3578 spare_buffer [len * 2] = '\n'; 3579 spare_buffer [len * 2 + 1] = '\0'; /* EOS */ 3580 gdb_puts (spare_buffer); 3581 } 3582 else 3583 gdb_puts ("Stack not collected\n"); 3584 3585 for (midx = 0; 3586 get_addr_to_a_mem_range (curframe.frame_data, 3587 midx, 3588 &mrange, 3589 (void **) &data) 3590 == OK_TARGET_RESPONSE; 3591 midx++) 3592 { 3593 if ((mrange->typecode == 0) || 3594 (mrange->typecode == (unsigned long) -1)) 3595 { 3596 sprintp (spare_buffer, 3597 " Collected %d bytes at MEM: 0x%x:\n", 3598 mrange->size, mrange->offset); 3599 base = (unsigned char *) mrange->offset; 3600 } 3601 else 3602 { 3603 if ((ridx = elinum_to_index (mrange->typecode)) > 0) 3604 base = (unsigned char *) curframe.traceregs[ridx] 3605 + (long) mrange->offset; 3606 else 3607 { 3608 sprintp (spare_buffer, 3609 "STUB: bad typecode in memrange #%d: (0x%x,0x%x,0x%x).\n", 3610 midx, 3611 mrange->typecode, 3612 mrange->offset, 3613 mrange->size); 3614 gdb_puts (spare_buffer); 3615 continue; 3616 } 3617 sprintp (spare_buffer, 3618 " Collected %d bytes at 0x%x (REG %X + %d):\n", 3619 mrange->size, 3620 base, 3621 mrange->typecode, 3622 mrange->offset); 3623 } 3624 gdb_puts (spare_buffer); 3625 len = mrange->size; 3626 if (len >= (NUMREGBYTES/2 - 2)) 3627 len = (NUMREGBYTES/2 - 3); 3628 mem2hex (data, spare_buffer, len, 0); 3629 spare_buffer [len * 2] = '\n'; 3630 spare_buffer [len * 2 + 1] = '\0'; /* EOS */ 3631 gdb_puts (spare_buffer); 3632 } 3633 } 3634 } 3635 sprintp (retbuf, "F%xT%x", n_frame, curframe.tdp_id & 0x7fffffff); 3636 return retbuf; 3637 } 3638 else if (ret == NOT_FOUND_TARGET_RESPONSE) 3639 { 3640 /* Here's a question: if the fetch_trace_frame call failed 3641 (which probably means a bad "TFIND" command from GDB), 3642 should we remain focused on the previous frame (if any), 3643 or should we revert to "no current frame"? 3644 */ 3645 return "F-1"; 3646 } 3647 else 3648 { 3649 sprintp (retbuf, "E2%x", ret); 3650 return (char *) dtc_error_ret ((int) &retbuf, 3651 "fetch_trace_frame[...]", 3652 ret); 3653 } 3654 } 3655 else /* unknown trace command */ 3656 { 3657 return ""; 3658 } 3659 } 3660 3661 /* Table used by the crc32 function to calcuate the checksum. */ 3662 static unsigned long crc32_table[256]; 3663 3664 static int crc_mem_err; 3665 3666 static unsigned long 3667 crc32 (buf, len, crc) 3668 unsigned char *buf; 3669 int len; 3670 unsigned long crc; 3671 { 3672 crc_mem_err = FALSE; 3673 3674 if (! crc32_table[1]) 3675 { 3676 /* Initialize the CRC table and the decoding table. */ 3677 int i, j; 3678 unsigned int c; 3679 3680 for (i = 0; i < 256; i++) 3681 { 3682 for (c = i << 24, j = 8; j > 0; --j) 3683 c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1); 3684 crc32_table[i] = c; 3685 } 3686 } 3687 3688 while (len--) 3689 { 3690 if (read_access_violation (buf)) 3691 { 3692 crc_mem_err = TRUE; 3693 return -1; 3694 } 3695 crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf++) & 255]; 3696 } 3697 return crc; 3698 } 3699 3700 static char * 3701 crc_query (cmd) 3702 char *cmd; 3703 { 3704 unsigned long startmem, len, crc; 3705 static char buf[32]; 3706 3707 if (hexToInt (&cmd, &startmem) && 3708 *cmd++ == ',' && 3709 hexToInt (&cmd, &len)) 3710 { 3711 crc = crc32 ((unsigned char *) startmem, len, 0xffffffff); 3712 if (!crc_mem_err) 3713 { 3714 sprintp (buf, "C%08x", crc); 3715 return buf; 3716 } 3717 /* else error, fall thru */ 3718 } 3719 sprintp (buf, "E01"); 3720 return buf; 3721 } 3722 3723 3724 static char * 3725 handle_test (request) 3726 char *request; 3727 { 3728 ULONG args[7]; 3729 int i; 3730 3731 /* Parse the arguments, a comma-separated list of hex numbers, into 3732 ARGS. Parse at most six arguments. */ 3733 i = 1; 3734 if (*request != '\0') 3735 while (i < 7) 3736 { 3737 if (! hexToInt (&request, &args[i++])) 3738 return "E01"; 3739 if (*request == '\0') 3740 break; 3741 if (*request++ != ',') 3742 return "E01"; 3743 } 3744 3745 /* Fill the rest of the args array with zeros. This is what the 3746 INLINES command processor does with omitted arguments. */ 3747 for (; i < 7; i++) 3748 args[i] = 0; 3749 3750 gdb_c_test (args); 3751 3752 return "OK"; 3753 } 3754 3755 3756 /* GDB_TRAP_1_HANDLER 3757 3758 By the time this is called, the registers have been saved in "registers", 3759 and the interrupt priority has been set to permit serial UART interrupts. 3760 3761 However, since no gdb request has yet been received, and there is no 3762 equivalent of getpacket for us to wait on, we can't sit here waiting 3763 for packets and processing them. 3764 3765 In fact, the ONLY thing for us to do here is sit and wait. 3766 As gdb sends packet requests, they will handle themselves at the 3767 interrupt level. When gdb decides we can continue, it will reset 3768 the global variable "gdb_handling_trap1", and we will return 3769 (whereupon registers will be restored etc.) */ 3770 3771 void gdb_trap_1_handler( void ) 3772 { 3773 gdb_handling_trap1 = TRUE; 3774 sss_trace_flag = '\0'; /* shut off "trace bit" (indirectly) */ 3775 gdb_signo = 5; 3776 putpacket( "S05" ); 3777 while ( gdb_handling_trap1 ) 3778 ; 3779 return; 3780 } 3781 3782 void gdb_trace_handler( void ) 3783 { 3784 sss_trace_flag = '\0'; /* shut off "trace bit" (indirectly) */ 3785 gdb_handling_trap1 = TRUE; 3786 gdb_handling_sstrace = TRUE; 3787 gdb_signo = 5; 3788 putpacket( "S05" ); 3789 while ( gdb_handling_trap1 ) 3790 ; 3791 return; 3792 } 3793