1 /* GDB interface to ARM RDI library. 2 3 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2004 Free Software 4 Foundation, Inc. 5 6 This file is part of GDB. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place - Suite 330, 21 Boston, MA 02111-1307, USA. */ 22 23 #include "defs.h" 24 #include "gdb_string.h" 25 #include <fcntl.h> 26 #include "frame.h" 27 #include "inferior.h" 28 #include "bfd.h" 29 #include "symfile.h" 30 #include "target.h" 31 #include "gdbcmd.h" 32 #include "objfiles.h" 33 #include "gdb-stabs.h" 34 #include "gdbthread.h" 35 #include "gdbcore.h" 36 #include "breakpoint.h" 37 #include "completer.h" 38 #include "regcache.h" 39 #include "arm-tdep.h" 40 41 #include <signal.h> 42 43 #include "rdi-share/ardi.h" 44 #include "rdi-share/adp.h" 45 #include "rdi-share/hsys.h" 46 47 extern int isascii (int); 48 49 /* Prototypes for local functions */ 50 51 static void arm_rdi_files_info (struct target_ops *ignore); 52 53 static int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, 54 int len, int should_write, 55 struct mem_attrib *attrib, 56 struct target_ops *target); 57 58 static void arm_rdi_prepare_to_store (void); 59 60 static void arm_rdi_fetch_registers (int regno); 61 62 static void arm_rdi_resume (ptid_t pid, int step, 63 enum target_signal siggnal); 64 65 static void arm_rdi_open (char *name, int from_tty); 66 67 static void arm_rdi_close (int quitting); 68 69 static void arm_rdi_store_registers (int regno); 70 71 static ptid_t arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status); 72 73 static void arm_rdi_kill (void); 74 75 static void arm_rdi_detach (char *args, int from_tty); 76 77 static int arm_rdi_insert_breakpoint (CORE_ADDR, char *); 78 79 static int arm_rdi_remove_breakpoint (CORE_ADDR, char *); 80 81 static char *rdi_error_message (int err); 82 83 static enum target_signal rdi_error_signal (int err); 84 85 /* Global variables. */ 86 87 struct target_ops arm_rdi_ops; 88 89 static struct Dbg_ConfigBlock gdb_config; 90 91 static struct Dbg_HostosInterface gdb_hostif; 92 93 static int max_load_size; 94 95 static int execute_status; 96 97 /* Send heatbeat packets? */ 98 static int rdi_heartbeat = 0; 99 100 /* Target has ROM at address 0. */ 101 static int rom_at_zero = 0; 102 103 /* Enable logging? */ 104 static int log_enable = 0; 105 106 /* Name of the log file. Default is "rdi.log". */ 107 static char *log_filename; 108 109 /* A little list of breakpoints that have been set. */ 110 111 static struct local_bp_list_entry 112 { 113 CORE_ADDR addr; 114 PointHandle point; 115 struct local_bp_list_entry *next; 116 } 117 *local_bp_list; 118 119 /* Helper callbacks for the "host interface" structure. RDI functions call 120 these to forward output from the target system and so forth. */ 121 122 static void 123 voiddummy (void *dummy) 124 { 125 fprintf_unfiltered (gdb_stdout, "void dummy\n"); 126 } 127 128 static void 129 myprint (void *arg, const char *format, va_list ap) 130 { 131 vfprintf_unfiltered (gdb_stdout, format, ap); 132 } 133 134 static void 135 mywritec (void *arg, int c) 136 { 137 if (isascii (c)) 138 fputc_unfiltered (c, gdb_stdout); 139 } 140 141 static int 142 mywrite (void *arg, char const *buffer, int len) 143 { 144 int i; 145 char *e; 146 147 e = (char *) buffer; 148 for (i = 0; i < len; i++) 149 { 150 if (isascii ((int) *e)) 151 { 152 fputc_unfiltered ((int) *e, gdb_stdout); 153 e++; 154 } 155 } 156 157 return len; 158 } 159 160 static void 161 mypause (void *arg) 162 { 163 } 164 165 /* These last two are tricky as we have to handle the special case of 166 being interrupted more carefully */ 167 168 static int 169 myreadc (void *arg) 170 { 171 return fgetc (stdin); 172 } 173 174 static char * 175 mygets (void *arg, char *buffer, int len) 176 { 177 return fgets (buffer, len, stdin); 178 } 179 180 /* Prevent multiple calls to angel_RDI_close(). */ 181 static int closed_already = 1; 182 183 /* Open a connection to a remote debugger. NAME is the filename used 184 for communication. */ 185 186 static void 187 arm_rdi_open (char *name, int from_tty) 188 { 189 int rslt, i; 190 unsigned long arg1, arg2; 191 char *openArgs = NULL; 192 char *devName = NULL; 193 char *p; 194 195 if (name == NULL) 196 error ("To open an RDI connection, you need to specify what serial\n\ 197 device is attached to the remote system (e.g. /dev/ttya)."); 198 199 /* split name after whitespace, pass tail as arg to open command */ 200 201 devName = xstrdup (name); 202 p = strchr (devName, ' '); 203 if (p) 204 { 205 *p = '\0'; 206 ++p; 207 208 while (*p == ' ') 209 ++p; 210 211 openArgs = p; 212 } 213 214 /* Make the basic low-level connection. */ 215 216 arm_rdi_close (0); 217 rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat); 218 219 if (rslt != adp_ok) 220 error ("Could not open device \"%s\"", name); 221 222 gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 1 : 0); 223 gdb_config.fpe = 1; 224 gdb_config.rditype = 2; 225 gdb_config.heartbeat_on = 1; 226 gdb_config.flags = 2; 227 228 gdb_hostif.dbgprint = myprint; 229 gdb_hostif.dbgpause = mypause; 230 gdb_hostif.dbgarg = NULL; 231 gdb_hostif.writec = mywritec; 232 gdb_hostif.readc = myreadc; 233 gdb_hostif.write = mywrite; 234 gdb_hostif.gets = mygets; 235 gdb_hostif.hostosarg = NULL; 236 gdb_hostif.reset = voiddummy; 237 238 rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL); 239 if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian) 240 ; /* do nothing, this is the expected return */ 241 else if (rslt != RDIError_NoError) 242 { 243 printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); 244 Adp_CloseDevice (); 245 error ("RDI_open failed\n"); 246 } 247 248 rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2); 249 if (rslt != RDIError_NoError) 250 { 251 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 252 } 253 rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2); 254 if (rslt != RDIError_NoError) 255 { 256 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 257 } 258 rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2); 259 if (rslt != RDIError_NoError) 260 { 261 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 262 } 263 rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2); 264 if (rslt != RDIError_NoError) 265 { 266 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 267 } 268 rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2); 269 if (rslt != RDIError_NoError) 270 { 271 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 272 } 273 274 rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2); 275 if (rslt != RDIError_NoError) 276 { 277 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 278 } 279 max_load_size = arg1; 280 281 push_target (&arm_rdi_ops); 282 283 target_fetch_registers (-1); 284 285 rslt = angel_RDI_open (1, &gdb_config, NULL, NULL); 286 if (rslt != RDIError_NoError) 287 { 288 printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); 289 } 290 291 arg1 = rom_at_zero ? 0x0 : 0x13b; 292 293 rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2); 294 if (rslt != RDIError_NoError) 295 { 296 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 297 } 298 299 arg1 = (unsigned long) ""; 300 rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2); 301 if (rslt != RDIError_NoError) 302 { 303 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 304 } 305 306 /* Clear out any existing records of breakpoints. */ 307 { 308 struct local_bp_list_entry *entry, *preventry = NULL; 309 310 for (entry = local_bp_list; entry != NULL; entry = entry->next) 311 { 312 if (preventry) 313 xfree (preventry); 314 } 315 } 316 317 printf_filtered ("Connected to ARM RDI target.\n"); 318 closed_already = 0; 319 inferior_ptid = pid_to_ptid (42); 320 } 321 322 /* Start an inferior process and set inferior_ptid to its pid. 323 EXEC_FILE is the file to run. 324 ARGS is a string containing the arguments to the program. 325 ENV is the environment vector to pass. Errors reported with error(). 326 On VxWorks and various standalone systems, we ignore exec_file. */ 327 /* This is called not only when we first attach, but also when the 328 user types "run" after having attached. */ 329 330 static void 331 arm_rdi_create_inferior (char *exec_file, char *args, char **env, int from_tty) 332 { 333 int len, rslt; 334 unsigned long arg1, arg2; 335 char *arg_buf; 336 CORE_ADDR entry_point; 337 338 if (exec_file == 0 || exec_bfd == 0) 339 error ("No executable file specified."); 340 341 entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd); 342 343 arm_rdi_kill (); 344 remove_breakpoints (); 345 init_wait_for_inferior (); 346 347 len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10; 348 arg_buf = (char *) alloca (len); 349 arg_buf[0] = '\0'; 350 strcat (arg_buf, exec_file); 351 strcat (arg_buf, " "); 352 strcat (arg_buf, args); 353 354 inferior_ptid = pid_to_ptid (42); 355 insert_breakpoints (); /* Needed to get correct instruction in cache */ 356 357 if (env != NULL) 358 { 359 while (*env) 360 { 361 if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0) 362 { 363 unsigned long top_of_memory; 364 char *end_of_num; 365 366 /* Set up memory limit */ 367 top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1, 368 &end_of_num, 0); 369 printf_filtered ("Setting top-of-memory to 0x%lx\n", 370 top_of_memory); 371 372 rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2); 373 if (rslt != RDIError_NoError) 374 { 375 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 376 } 377 } 378 env++; 379 } 380 } 381 382 arg1 = (unsigned long) arg_buf; 383 rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2); 384 if (rslt != RDIError_NoError) 385 { 386 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 387 } 388 389 proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0); 390 } 391 392 /* This takes a program previously attached to and detaches it. After 393 this is done, GDB can be used to debug some other program. We 394 better not have left any breakpoints in the target program or it'll 395 die when it hits one. */ 396 397 static void 398 arm_rdi_detach (char *args, int from_tty) 399 { 400 pop_target (); 401 } 402 403 /* Clean up connection to a remote debugger. */ 404 405 static void 406 arm_rdi_close (int quitting) 407 { 408 int rslt; 409 410 if (!closed_already) 411 { 412 rslt = angel_RDI_close (); 413 if (rslt != RDIError_NoError) 414 { 415 printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt)); 416 } 417 closed_already = 1; 418 inferior_ptid = null_ptid; 419 Adp_CloseDevice (); 420 generic_mourn_inferior (); 421 } 422 } 423 424 /* Tell the remote machine to resume. */ 425 426 static void 427 arm_rdi_resume (ptid_t ptid, int step, enum target_signal siggnal) 428 { 429 int rslt; 430 PointHandle point; 431 432 if (0 /* turn on when hardware supports single-stepping */ ) 433 { 434 rslt = angel_RDI_step (1, &point); 435 if (rslt != RDIError_NoError) 436 printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt)); 437 } 438 else 439 { 440 char handle[4]; 441 CORE_ADDR pc = 0; 442 443 if (step) 444 { 445 pc = read_register (ARM_PC_REGNUM); 446 pc = arm_get_next_pc (pc); 447 arm_rdi_insert_breakpoint (pc, handle); 448 } 449 450 execute_status = rslt = angel_RDI_execute (&point); 451 if (rslt != RDIError_NoError && rslt != RDIError_BreakpointReached) 452 printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt)); 453 454 if (step) 455 arm_rdi_remove_breakpoint (pc, handle); 456 } 457 } 458 459 /* Wait until the remote machine stops, then return, storing status in 460 STATUS just as `wait' would. Returns "pid" (though it's not clear 461 what, if anything, that means in the case of this target). */ 462 463 static ptid_t 464 arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status) 465 { 466 status->kind = (execute_status == RDIError_NoError ? 467 TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED); 468 469 /* convert stopped code from target into right signal */ 470 status->value.sig = rdi_error_signal (execute_status); 471 472 return inferior_ptid; 473 } 474 475 /* Read the remote registers into the block REGS. */ 476 477 static void 478 arm_rdi_fetch_registers (int regno) 479 { 480 int rslt, rdi_regmask; 481 unsigned long rawreg, rawregs[32]; 482 char cookedreg[4]; 483 484 if (regno == -1) 485 { 486 rslt = angel_RDI_CPUread (255, 0x27fff, rawregs); 487 if (rslt != RDIError_NoError) 488 { 489 printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt)); 490 } 491 492 for (regno = 0; regno < 15; regno++) 493 { 494 store_unsigned_integer (cookedreg, 4, rawregs[regno]); 495 regcache_raw_supply (current_regcache, regno, (char *) cookedreg); 496 } 497 store_unsigned_integer (cookedreg, 4, rawregs[15]); 498 regcache_raw_supply (current_regcache, ARM_PS_REGNUM, (char *) cookedreg); 499 arm_rdi_fetch_registers (ARM_PC_REGNUM); 500 } 501 else 502 { 503 if (regno == ARM_PC_REGNUM) 504 rdi_regmask = RDIReg_PC; 505 else if (regno == ARM_PS_REGNUM) 506 rdi_regmask = RDIReg_CPSR; 507 else if (regno < 0 || regno > 15) 508 { 509 rawreg = 0; 510 regcache_raw_supply (current_regcache, regno, (char *) &rawreg); 511 return; 512 } 513 else 514 rdi_regmask = 1 << regno; 515 516 rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg); 517 if (rslt != RDIError_NoError) 518 { 519 printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt)); 520 } 521 store_unsigned_integer (cookedreg, 4, rawreg); 522 regcache_raw_supply (current_regcache, regno, (char *) cookedreg); 523 } 524 } 525 526 static void 527 arm_rdi_prepare_to_store (void) 528 { 529 /* Nothing to do. */ 530 } 531 532 /* Store register REGNO, or all registers if REGNO == -1, from the contents 533 of REGISTERS. FIXME: ignores errors. */ 534 535 static void 536 arm_rdi_store_registers (int regno) 537 { 538 int rslt, rdi_regmask; 539 540 /* These need to be able to take 'floating point register' contents */ 541 unsigned long rawreg[3], rawerreg[3]; 542 543 if (regno == -1) 544 { 545 for (regno = 0; regno < NUM_REGS; regno++) 546 arm_rdi_store_registers (regno); 547 } 548 else 549 { 550 deprecated_read_register_gen (regno, (char *) rawreg); 551 /* RDI manipulates data in host byte order, so convert now. */ 552 store_unsigned_integer (rawerreg, 4, rawreg[0]); 553 554 if (regno == ARM_PC_REGNUM) 555 rdi_regmask = RDIReg_PC; 556 else if (regno == ARM_PS_REGNUM) 557 rdi_regmask = RDIReg_CPSR; 558 else if (regno < 0 || regno > 15) 559 return; 560 else 561 rdi_regmask = 1 << regno; 562 563 rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg); 564 if (rslt != RDIError_NoError) 565 { 566 printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt)); 567 } 568 } 569 } 570 571 /* Read or write LEN bytes from inferior memory at MEMADDR, 572 transferring to or from debugger address MYADDR. Write to inferior 573 if SHOULD_WRITE is nonzero. Returns length of data written or 574 read; 0 for error. TARGET is unused. */ 575 576 static int 577 arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, 578 int should_write, struct mem_attrib *attrib, 579 struct target_ops *target) 580 { 581 int rslt, i; 582 583 if (should_write) 584 { 585 rslt = angel_RDI_write (myaddr, memaddr, &len); 586 if (rslt != RDIError_NoError) 587 { 588 printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt)); 589 } 590 } 591 else 592 { 593 rslt = angel_RDI_read (memaddr, myaddr, &len); 594 if (rslt != RDIError_NoError) 595 { 596 printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt)); 597 len = 0; 598 } 599 } 600 return len; 601 } 602 603 /* Display random info collected from the target. */ 604 605 static void 606 arm_rdi_files_info (struct target_ops *ignore) 607 { 608 char *file = "nothing"; 609 int rslt; 610 unsigned long arg1, arg2; 611 612 rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2); 613 if (rslt != RDIError_NoError) 614 { 615 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 616 } 617 if (arg1 & (1 << 15)) 618 printf_filtered ("Target supports Thumb code.\n"); 619 if (arg1 & (1 << 14)) 620 printf_filtered ("Target can do profiling.\n"); 621 if (arg1 & (1 << 4)) 622 printf_filtered ("Target is real hardware.\n"); 623 624 rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2); 625 if (rslt != RDIError_NoError) 626 { 627 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 628 } 629 printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not")); 630 631 rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2); 632 if (rslt != RDIError_NoError) 633 { 634 printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 635 } 636 else 637 printf_filtered ("Target includes an EmbeddedICE.\n"); 638 } 639 640 static void 641 arm_rdi_kill (void) 642 { 643 int rslt; 644 645 rslt = angel_RDI_open (1, &gdb_config, NULL, NULL); 646 if (rslt != RDIError_NoError) 647 { 648 printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); 649 } 650 } 651 652 static void 653 arm_rdi_mourn_inferior (void) 654 { 655 /* We remove the inserted breakpoints in case the user wants to 656 issue another target and load commands to rerun his application; 657 This is something that wouldn't work on a native target, for instance, 658 as the process goes away when the inferior exits, but it works with 659 some remote targets like this one. That is why this is done here. */ 660 remove_breakpoints(); 661 unpush_target (&arm_rdi_ops); 662 generic_mourn_inferior (); 663 } 664 665 /* While the RDI library keeps track of its own breakpoints, we need 666 to remember "handles" so that we can delete them later. Since 667 breakpoints get used for stepping, be careful not to leak memory 668 here. */ 669 670 static int 671 arm_rdi_insert_breakpoint (CORE_ADDR addr, char *contents_cache) 672 { 673 int rslt; 674 PointHandle point; 675 struct local_bp_list_entry *entry; 676 int type = RDIPoint_EQ; 677 678 if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr)) 679 type |= RDIPoint_16Bit; 680 rslt = angel_RDI_setbreak (addr, type, 0, &point); 681 if (rslt != RDIError_NoError) 682 { 683 printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt)); 684 } 685 entry = 686 (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry)); 687 entry->addr = addr; 688 entry->point = point; 689 entry->next = local_bp_list; 690 local_bp_list = entry; 691 return rslt; 692 } 693 694 static int 695 arm_rdi_remove_breakpoint (CORE_ADDR addr, char *contents_cache) 696 { 697 int rslt; 698 PointHandle point; 699 struct local_bp_list_entry **entryp, *dead; 700 701 for (entryp = &local_bp_list; *entryp != NULL; entryp = &(*entryp)->next) 702 if ((*entryp)->addr == addr) 703 break; 704 705 if (*entryp) 706 { 707 dead = *entryp; 708 rslt = angel_RDI_clearbreak (dead->point); 709 if (rslt != RDIError_NoError) 710 printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt)); 711 712 /* Delete the breakpoint entry locally. */ 713 *entryp = dead->next; 714 xfree (dead); 715 } 716 717 return 0; 718 } 719 720 721 static char * 722 rdi_error_message (int err) 723 { 724 switch (err) 725 { 726 case RDIError_NoError: 727 return "no error"; 728 case RDIError_Reset: 729 return "debuggee reset"; 730 case RDIError_UndefinedInstruction: 731 return "undefined instruction"; 732 case RDIError_SoftwareInterrupt: 733 return "SWI trapped"; 734 case RDIError_PrefetchAbort: 735 return "prefetch abort, execution ran into unmapped memory?"; 736 case RDIError_DataAbort: 737 return "data abort, no memory at specified address?"; 738 case RDIError_AddressException: 739 return "address exception, access >26bit in 26bit mode"; 740 case RDIError_IRQ: 741 return "IRQ, interrupt trapped"; 742 case RDIError_FIQ: 743 return "FIQ, fast interrupt trapped"; 744 case RDIError_Error: 745 return "a miscellaneous type of error"; 746 case RDIError_BranchThrough0: 747 return "branch through location 0"; 748 case RDIError_NotInitialised: 749 return "internal error, RDI_open not called first"; 750 case RDIError_UnableToInitialise: 751 return "internal error, target world is broken"; 752 case RDIError_WrongByteSex: 753 return "See Operator: WrongByteSex"; 754 case RDIError_UnableToTerminate: 755 return "See Operator: Unable to Terminate"; 756 case RDIError_BadInstruction: 757 return "bad instruction, illegal to execute this instruction"; 758 case RDIError_IllegalInstruction: 759 return "illegal instruction, the effect of executing it is undefined"; 760 case RDIError_BadCPUStateSetting: 761 return "internal error, tried to set SPSR of user mode"; 762 case RDIError_UnknownCoPro: 763 return "unknown co-processor"; 764 case RDIError_UnknownCoProState: 765 return "cannot execute co-processor request"; 766 case RDIError_BadCoProState: 767 return "recognizably broken co-processor request"; 768 case RDIError_BadPointType: 769 return "internal error, bad point yype"; 770 case RDIError_UnimplementedType: 771 return "internal error, unimplemented type"; 772 case RDIError_BadPointSize: 773 return "internal error, bad point size"; 774 case RDIError_UnimplementedSize: 775 return "internal error, unimplemented size"; 776 case RDIError_NoMorePoints: 777 return "last break/watch point was used"; 778 case RDIError_BreakpointReached: 779 return "breakpoint reached"; 780 case RDIError_WatchpointAccessed: 781 return "watchpoint accessed"; 782 case RDIError_NoSuchPoint: 783 return "attempted to clear non-existent break/watch point"; 784 case RDIError_ProgramFinishedInStep: 785 return "end of the program reached while stepping"; 786 case RDIError_UserInterrupt: 787 return "you pressed Escape"; 788 case RDIError_CantSetPoint: 789 return "no more break/watch points available"; 790 case RDIError_IncompatibleRDILevels: 791 return "incompatible RDI levels"; 792 case RDIError_LittleEndian: 793 return "debuggee is little endian"; 794 case RDIError_BigEndian: 795 return "debuggee is big endian"; 796 case RDIError_SoftInitialiseError: 797 return "recoverable error in RDI initialization"; 798 case RDIError_InsufficientPrivilege: 799 return "internal error, supervisor state not accessible to monitor"; 800 case RDIError_UnimplementedMessage: 801 return "internal error, unimplemented message"; 802 case RDIError_UndefinedMessage: 803 return "internal error, undefined message"; 804 default: 805 return "undefined error message, should reset target"; 806 } 807 } 808 809 /* Convert the ARM error messages to signals that GDB knows about. */ 810 811 static enum target_signal 812 rdi_error_signal (int err) 813 { 814 switch (err) 815 { 816 case RDIError_NoError: 817 return 0; 818 case RDIError_Reset: 819 return TARGET_SIGNAL_TERM; /* ??? */ 820 case RDIError_UndefinedInstruction: 821 return TARGET_SIGNAL_ILL; 822 case RDIError_SoftwareInterrupt: 823 case RDIError_PrefetchAbort: 824 case RDIError_DataAbort: 825 return TARGET_SIGNAL_TRAP; 826 case RDIError_AddressException: 827 return TARGET_SIGNAL_SEGV; 828 case RDIError_IRQ: 829 case RDIError_FIQ: 830 return TARGET_SIGNAL_TRAP; 831 case RDIError_Error: 832 return TARGET_SIGNAL_TERM; 833 case RDIError_BranchThrough0: 834 return TARGET_SIGNAL_TRAP; 835 case RDIError_NotInitialised: 836 case RDIError_UnableToInitialise: 837 case RDIError_WrongByteSex: 838 case RDIError_UnableToTerminate: 839 return TARGET_SIGNAL_UNKNOWN; 840 case RDIError_BadInstruction: 841 case RDIError_IllegalInstruction: 842 return TARGET_SIGNAL_ILL; 843 case RDIError_BadCPUStateSetting: 844 case RDIError_UnknownCoPro: 845 case RDIError_UnknownCoProState: 846 case RDIError_BadCoProState: 847 case RDIError_BadPointType: 848 case RDIError_UnimplementedType: 849 case RDIError_BadPointSize: 850 case RDIError_UnimplementedSize: 851 case RDIError_NoMorePoints: 852 return TARGET_SIGNAL_UNKNOWN; 853 case RDIError_BreakpointReached: 854 case RDIError_WatchpointAccessed: 855 return TARGET_SIGNAL_TRAP; 856 case RDIError_NoSuchPoint: 857 case RDIError_ProgramFinishedInStep: 858 return TARGET_SIGNAL_UNKNOWN; 859 case RDIError_UserInterrupt: 860 return TARGET_SIGNAL_INT; 861 case RDIError_IncompatibleRDILevels: 862 case RDIError_LittleEndian: 863 case RDIError_BigEndian: 864 case RDIError_SoftInitialiseError: 865 case RDIError_InsufficientPrivilege: 866 case RDIError_UnimplementedMessage: 867 case RDIError_UndefinedMessage: 868 default: 869 return TARGET_SIGNAL_UNKNOWN; 870 } 871 } 872 873 static void 874 arm_rdi_stop(void) 875 { 876 angel_RDI_stop_request(); 877 } 878 879 880 /* Define the target operations structure. */ 881 882 static void 883 init_rdi_ops (void) 884 { 885 arm_rdi_ops.to_shortname = "rdi"; 886 arm_rdi_ops.to_longname = "ARM RDI"; 887 arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\ 888 Specify the serial device it is connected to (e.g. /dev/ttya)."; 889 arm_rdi_ops.to_open = arm_rdi_open; 890 arm_rdi_ops.to_close = arm_rdi_close; 891 arm_rdi_ops.to_detach = arm_rdi_detach; 892 arm_rdi_ops.to_resume = arm_rdi_resume; 893 arm_rdi_ops.to_wait = arm_rdi_wait; 894 arm_rdi_ops.to_stop = arm_rdi_stop; 895 arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers; 896 arm_rdi_ops.to_store_registers = arm_rdi_store_registers; 897 arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store; 898 arm_rdi_ops.deprecated_xfer_memory = arm_rdi_xfer_memory; 899 arm_rdi_ops.to_files_info = arm_rdi_files_info; 900 arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint; 901 arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint; 902 arm_rdi_ops.to_kill = arm_rdi_kill; 903 arm_rdi_ops.to_load = generic_load; 904 arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior; 905 arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior; 906 arm_rdi_ops.to_stratum = process_stratum; 907 arm_rdi_ops.to_has_all_memory = 1; 908 arm_rdi_ops.to_has_memory = 1; 909 arm_rdi_ops.to_has_stack = 1; 910 arm_rdi_ops.to_has_registers = 1; 911 arm_rdi_ops.to_has_execution = 1; 912 arm_rdi_ops.to_magic = OPS_MAGIC; 913 } 914 915 static void 916 rdilogfile_command (char *arg, int from_tty) 917 { 918 if (!arg || strlen (arg) == 0) 919 { 920 printf_filtered ("rdi log file is '%s'\n", log_filename); 921 return; 922 } 923 924 if (log_filename) 925 xfree (log_filename); 926 927 log_filename = xstrdup (arg); 928 929 Adp_SetLogfile (log_filename); 930 } 931 932 static void 933 rdilogenable_command (char *args, int from_tty) 934 { 935 if (!args || strlen (args) == 0) 936 { 937 printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled"); 938 return; 939 } 940 941 if (!strcasecmp (args, "1") || 942 !strcasecmp (args, "y") || 943 !strcasecmp (args, "yes") || 944 !strcasecmp (args, "on") || 945 !strcasecmp (args, "t") || 946 !strcasecmp (args, "true")) 947 Adp_SetLogEnable (log_enable = 1); 948 else if (!strcasecmp (args, "0") || 949 !strcasecmp (args, "n") || 950 !strcasecmp (args, "no") || 951 !strcasecmp (args, "off") || 952 !strcasecmp (args, "f") || 953 !strcasecmp (args, "false")) 954 Adp_SetLogEnable (log_enable = 0); 955 else 956 printf_filtered ("rdilogenable: unrecognized argument '%s'\n" 957 " try y or n\n", args); 958 } 959 960 extern initialize_file_ftype _initialize_remote_rdi; /* -Wmissing-prototypes */ 961 962 void 963 _initialize_remote_rdi (void) 964 { 965 struct cmd_list_element *c; 966 967 init_rdi_ops (); 968 add_target (&arm_rdi_ops); 969 970 log_filename = xstrdup ("rdi.log"); 971 Adp_SetLogfile (log_filename); 972 Adp_SetLogEnable (log_enable); 973 974 c = add_cmd ("rdilogfile", class_maintenance, 975 rdilogfile_command, 976 "Set filename for ADP packet log.\n" 977 "This file is used to log Angel Debugger Protocol packets.\n" 978 "With a single argument, sets the logfile name to that value.\n" 979 "Without an argument, shows the current logfile name.\n" 980 "See also: rdilogenable\n", 981 &maintenancelist); 982 set_cmd_completer (c, filename_completer); 983 984 add_cmd ("rdilogenable", class_maintenance, 985 rdilogenable_command, 986 "Set enable logging of ADP packets.\n" 987 "This will log ADP packets exchanged between gdb and the\n" 988 "rdi target device.\n" 989 "An argument of 1, t, true, y or yes will enable.\n" 990 "An argument of 0, f, false, n or no will disabled.\n" 991 "Withough an argument, it will display current state.\n", 992 &maintenancelist); 993 994 add_setshow_boolean_cmd ("rdiromatzero", no_class, &rom_at_zero, "\ 995 Set target has ROM at addr 0.", "\ 996 Show if target has ROM at addr 0.", "\ 997 A true value disables vector catching, false enables vector catching.\n\ 998 This is evaluated at the time the 'target rdi' command is executed.", "\ 999 Target has ROM at addr 0 is %s.", 1000 NULL, NULL, 1001 &setlist, &showlist); 1002 1003 add_setshow_boolean_cmd ("rdiheartbeat", no_class, &rdi_heartbeat, "\ 1004 Set enable for ADP heartbeat packets.", "\ 1005 Show enable for ADP heartbeat packets.", "\ 1006 I don't know why you would want this. If you enable them,\n\ 1007 it will confuse ARM and EPI JTAG interface boxes as well\n\ 1008 as the Angel Monitor.", "\ 1009 Enable for ADP heartbeat packets is %s.", 1010 NULL, NULL, 1011 &setlist, &showlist); 1012 } 1013 1014 /* A little dummy to make linking with the library succeed. */ 1015 1016 void 1017 Fail (const char *ignored, ...) 1018 { 1019 1020 } 1021