146283Sdfr/* GDB interface to ARM RDI library. 246283Sdfr 398944Sobrien Copyright 1997, 1998, 1999, 2000, 2001, 2002 Free Software 498944Sobrien Foundation, Inc. 546283Sdfr 698944Sobrien This file is part of GDB. 746283Sdfr 898944Sobrien This program is free software; you can redistribute it and/or modify 998944Sobrien it under the terms of the GNU General Public License as published by 1098944Sobrien the Free Software Foundation; either version 2 of the License, or 1198944Sobrien (at your option) any later version. 1246283Sdfr 1398944Sobrien This program is distributed in the hope that it will be useful, 1498944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1598944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1698944Sobrien GNU General Public License for more details. 1746283Sdfr 1898944Sobrien You should have received a copy of the GNU General Public License 1998944Sobrien along with this program; if not, write to the Free Software 2098944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2198944Sobrien Boston, MA 02111-1307, USA. */ 2298944Sobrien 2346283Sdfr#include "defs.h" 2446283Sdfr#include "gdb_string.h" 2546283Sdfr#include <fcntl.h> 2646283Sdfr#include "frame.h" 2746283Sdfr#include "inferior.h" 2846283Sdfr#include "bfd.h" 2946283Sdfr#include "symfile.h" 3046283Sdfr#include "target.h" 3146283Sdfr#include "gdbcmd.h" 3246283Sdfr#include "objfiles.h" 3346283Sdfr#include "gdb-stabs.h" 3446283Sdfr#include "gdbthread.h" 3546283Sdfr#include "gdbcore.h" 3698944Sobrien#include "breakpoint.h" 3798944Sobrien#include "completer.h" 3898944Sobrien#include "regcache.h" 3998944Sobrien#include "arm-tdep.h" 4046283Sdfr 4146283Sdfr#ifdef USG 4246283Sdfr#include <sys/types.h> 4346283Sdfr#endif 4446283Sdfr 4546283Sdfr#include <signal.h> 4646283Sdfr 4746283Sdfr#include "rdi-share/ardi.h" 4846283Sdfr#include "rdi-share/adp.h" 4946283Sdfr#include "rdi-share/hsys.h" 5046283Sdfr 5198944Sobrienextern int isascii (int); 5246283Sdfr 5346283Sdfr/* Prototypes for local functions */ 5446283Sdfr 5598944Sobrienstatic void arm_rdi_files_info (struct target_ops *ignore); 5646283Sdfr 5798944Sobrienstatic int arm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, 5898944Sobrien int len, int should_write, 5998944Sobrien struct mem_attrib *attrib, 6098944Sobrien struct target_ops *target); 6146283Sdfr 6298944Sobrienstatic void arm_rdi_prepare_to_store (void); 6346283Sdfr 6498944Sobrienstatic void arm_rdi_fetch_registers (int regno); 6546283Sdfr 6698944Sobrienstatic void arm_rdi_resume (ptid_t pid, int step, 6798944Sobrien enum target_signal siggnal); 6846283Sdfr 6998944Sobrienstatic void arm_rdi_open (char *name, int from_tty); 7046283Sdfr 7198944Sobrienstatic void arm_rdi_create_inferior (char *exec_file, char *args, char **env); 7246283Sdfr 7398944Sobrienstatic void arm_rdi_close (int quitting); 7446283Sdfr 7598944Sobrienstatic void arm_rdi_store_registers (int regno); 7646283Sdfr 7798944Sobrienstatic ptid_t arm_rdi_wait (ptid_t ptid, struct target_waitstatus *status); 7846283Sdfr 7998944Sobrienstatic void arm_rdi_kill (void); 8046283Sdfr 8198944Sobrienstatic void arm_rdi_detach (char *args, int from_tty); 8246283Sdfr 8398944Sobrienstatic int arm_rdi_insert_breakpoint (CORE_ADDR, char *); 8446283Sdfr 8598944Sobrienstatic int arm_rdi_remove_breakpoint (CORE_ADDR, char *); 8646283Sdfr 8798944Sobrienstatic char *rdi_error_message (int err); 8846283Sdfr 8998944Sobrienstatic enum target_signal rdi_error_signal (int err); 9046283Sdfr 9146283Sdfr/* Global variables. */ 9246283Sdfr 9346283Sdfrstruct target_ops arm_rdi_ops; 9446283Sdfr 9546283Sdfrstatic struct Dbg_ConfigBlock gdb_config; 9646283Sdfr 9746283Sdfrstatic struct Dbg_HostosInterface gdb_hostif; 9846283Sdfr 9946283Sdfrstatic int max_load_size; 10046283Sdfr 10146283Sdfrstatic int execute_status; 10246283Sdfr 10398944Sobrien/* Send heatbeat packets? */ 10498944Sobrienstatic int rdi_heartbeat = 0; 10598944Sobrien 10698944Sobrien/* Target has ROM at address 0. */ 10798944Sobrienstatic int rom_at_zero = 0; 10898944Sobrien 10998944Sobrien/* Enable logging? */ 11098944Sobrienstatic int log_enable = 0; 11198944Sobrien 11298944Sobrien/* Name of the log file. Default is "rdi.log". */ 11398944Sobrienstatic char *log_filename; 11498944Sobrien 11546283Sdfr/* A little list of breakpoints that have been set. */ 11646283Sdfr 11798944Sobrienstatic struct local_bp_list_entry 11898944Sobrien { 11998944Sobrien CORE_ADDR addr; 12098944Sobrien PointHandle point; 12198944Sobrien struct local_bp_list_entry *next; 12298944Sobrien } 12398944Sobrien *local_bp_list; 12498944Sobrien 12546283Sdfr/* Helper callbacks for the "host interface" structure. RDI functions call 12646283Sdfr these to forward output from the target system and so forth. */ 12746283Sdfr 128130803Smarcelstatic void 12998944Sobrienvoiddummy (void *dummy) 13046283Sdfr{ 13146283Sdfr fprintf_unfiltered (gdb_stdout, "void dummy\n"); 13246283Sdfr} 13346283Sdfr 13446283Sdfrstatic void 135130803Smarcelmyprint (void *arg, const char *format, va_list ap) 13646283Sdfr{ 13746283Sdfr vfprintf_unfiltered (gdb_stdout, format, ap); 13846283Sdfr} 13946283Sdfr 14046283Sdfrstatic void 141130803Smarcelmywritec (void *arg, int c) 14246283Sdfr{ 14346283Sdfr if (isascii (c)) 14446283Sdfr fputc_unfiltered (c, gdb_stdout); 14546283Sdfr} 14646283Sdfr 14746283Sdfrstatic int 148130803Smarcelmywrite (void *arg, char const *buffer, int len) 14946283Sdfr{ 15046283Sdfr int i; 15146283Sdfr char *e; 15246283Sdfr 15346283Sdfr e = (char *) buffer; 15446283Sdfr for (i = 0; i < len; i++) 15598944Sobrien { 15646283Sdfr if (isascii ((int) *e)) 15798944Sobrien { 15898944Sobrien fputc_unfiltered ((int) *e, gdb_stdout); 15998944Sobrien e++; 16098944Sobrien } 16198944Sobrien } 16246283Sdfr 16346283Sdfr return len; 16446283Sdfr} 16546283Sdfr 16646283Sdfrstatic void 167130803Smarcelmypause (void *arg) 16846283Sdfr{ 16946283Sdfr} 17046283Sdfr 17146283Sdfr/* These last two are tricky as we have to handle the special case of 17246283Sdfr being interrupted more carefully */ 17346283Sdfr 17446283Sdfrstatic int 175130803Smarcelmyreadc (void *arg) 17698944Sobrien{ 17746283Sdfr return fgetc (stdin); 17846283Sdfr} 17946283Sdfr 18046283Sdfrstatic char * 181130803Smarcelmygets (void *arg, char *buffer, int len) 18246283Sdfr{ 18398944Sobrien return fgets (buffer, len, stdin); 18446283Sdfr} 18546283Sdfr 18646283Sdfr/* Prevent multiple calls to angel_RDI_close(). */ 18746283Sdfrstatic int closed_already = 1; 18846283Sdfr 18946283Sdfr/* Open a connection to a remote debugger. NAME is the filename used 19046283Sdfr for communication. */ 19146283Sdfr 19246283Sdfrstatic void 19398944Sobrienarm_rdi_open (char *name, int from_tty) 19446283Sdfr{ 19546283Sdfr int rslt, i; 19646283Sdfr unsigned long arg1, arg2; 19798944Sobrien char *openArgs = NULL; 19898944Sobrien char *devName = NULL; 19998944Sobrien char *p; 20046283Sdfr 20146283Sdfr if (name == NULL) 20246283Sdfr error ("To open an RDI connection, you need to specify what serial\n\ 20346283Sdfrdevice is attached to the remote system (e.g. /dev/ttya)."); 20446283Sdfr 20598944Sobrien /* split name after whitespace, pass tail as arg to open command */ 20698944Sobrien 20798944Sobrien devName = xstrdup (name); 20898944Sobrien p = strchr (devName, ' '); 20998944Sobrien if (p) 21098944Sobrien { 21198944Sobrien *p = '\0'; 21298944Sobrien ++p; 21398944Sobrien 21498944Sobrien while (*p == ' ') 21598944Sobrien ++p; 21698944Sobrien 21798944Sobrien openArgs = p; 21898944Sobrien } 21998944Sobrien 22046283Sdfr /* Make the basic low-level connection. */ 22146283Sdfr 22298944Sobrien arm_rdi_close (0); 22398944Sobrien rslt = Adp_OpenDevice (devName, openArgs, rdi_heartbeat); 22446283Sdfr 22546283Sdfr if (rslt != adp_ok) 22646283Sdfr error ("Could not open device \"%s\"", name); 22746283Sdfr 22898944Sobrien gdb_config.bytesex = 2 | (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 1 : 0); 22946283Sdfr gdb_config.fpe = 1; 23046283Sdfr gdb_config.rditype = 2; 23146283Sdfr gdb_config.heartbeat_on = 1; 23246283Sdfr gdb_config.flags = 2; 23346283Sdfr 23446283Sdfr gdb_hostif.dbgprint = myprint; 23546283Sdfr gdb_hostif.dbgpause = mypause; 23646283Sdfr gdb_hostif.dbgarg = NULL; 23746283Sdfr gdb_hostif.writec = mywritec; 23846283Sdfr gdb_hostif.readc = myreadc; 23946283Sdfr gdb_hostif.write = mywrite; 24046283Sdfr gdb_hostif.gets = mygets; 24146283Sdfr gdb_hostif.hostosarg = NULL; 24246283Sdfr gdb_hostif.reset = voiddummy; 24346283Sdfr 24446283Sdfr rslt = angel_RDI_open (10, &gdb_config, &gdb_hostif, NULL); 24546283Sdfr if (rslt == RDIError_BigEndian || rslt == RDIError_LittleEndian) 24698944Sobrien ; /* do nothing, this is the expected return */ 247130803Smarcel else if (rslt != RDIError_NoError) 24846283Sdfr { 24946283Sdfr printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); 25098944Sobrien Adp_CloseDevice (); 25198944Sobrien error ("RDI_open failed\n"); 25246283Sdfr } 25346283Sdfr 25446283Sdfr rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2); 255130803Smarcel if (rslt != RDIError_NoError) 25646283Sdfr { 25746283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 25846283Sdfr } 25946283Sdfr rslt = angel_RDI_info (RDIInfo_Points, &arg1, &arg2); 260130803Smarcel if (rslt != RDIError_NoError) 26146283Sdfr { 26246283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 26346283Sdfr } 26446283Sdfr rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2); 265130803Smarcel if (rslt != RDIError_NoError) 26646283Sdfr { 26746283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 26846283Sdfr } 26946283Sdfr rslt = angel_RDI_info (RDIInfo_CoPro, &arg1, &arg2); 270130803Smarcel if (rslt != RDIError_NoError) 27146283Sdfr { 27246283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 27346283Sdfr } 27446283Sdfr rslt = angel_RDI_info (RDIInfo_SemiHosting, &arg1, &arg2); 275130803Smarcel if (rslt != RDIError_NoError) 27646283Sdfr { 27746283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 27846283Sdfr } 27946283Sdfr 28046283Sdfr rslt = angel_RDI_info (RDIInfo_GetLoadSize, &arg1, &arg2); 281130803Smarcel if (rslt != RDIError_NoError) 28246283Sdfr { 28346283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 28446283Sdfr } 28546283Sdfr max_load_size = arg1; 28646283Sdfr 28746283Sdfr push_target (&arm_rdi_ops); 28846283Sdfr 28946283Sdfr target_fetch_registers (-1); 29046283Sdfr 29146283Sdfr rslt = angel_RDI_open (1, &gdb_config, NULL, NULL); 292130803Smarcel if (rslt != RDIError_NoError) 29346283Sdfr { 29446283Sdfr printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); 29546283Sdfr } 29646283Sdfr 29798944Sobrien arg1 = rom_at_zero ? 0x0 : 0x13b; 29898944Sobrien 29946283Sdfr rslt = angel_RDI_info (RDIVector_Catch, &arg1, &arg2); 300130803Smarcel if (rslt != RDIError_NoError) 30146283Sdfr { 30246283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 30346283Sdfr } 30446283Sdfr 30546283Sdfr arg1 = (unsigned long) ""; 30646283Sdfr rslt = angel_RDI_info (RDISet_Cmdline, &arg1, &arg2); 307130803Smarcel if (rslt != RDIError_NoError) 30846283Sdfr { 30946283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 31046283Sdfr } 31146283Sdfr 31246283Sdfr /* Clear out any existing records of breakpoints. */ 31346283Sdfr { 31446283Sdfr struct local_bp_list_entry *entry, *preventry = NULL; 31546283Sdfr 31646283Sdfr for (entry = local_bp_list; entry != NULL; entry = entry->next) 31746283Sdfr { 31846283Sdfr if (preventry) 31998944Sobrien xfree (preventry); 32046283Sdfr } 32146283Sdfr } 32246283Sdfr 32346283Sdfr printf_filtered ("Connected to ARM RDI target.\n"); 32446283Sdfr closed_already = 0; 32598944Sobrien inferior_ptid = pid_to_ptid (42); 32646283Sdfr} 32746283Sdfr 32898944Sobrien/* Start an inferior process and set inferior_ptid to its pid. 32946283Sdfr EXEC_FILE is the file to run. 33046283Sdfr ARGS is a string containing the arguments to the program. 33146283Sdfr ENV is the environment vector to pass. Errors reported with error(). 33246283Sdfr On VxWorks and various standalone systems, we ignore exec_file. */ 33346283Sdfr/* This is called not only when we first attach, but also when the 33446283Sdfr user types "run" after having attached. */ 33546283Sdfr 33646283Sdfrstatic void 33798944Sobrienarm_rdi_create_inferior (char *exec_file, char *args, char **env) 33846283Sdfr{ 33946283Sdfr int len, rslt; 34046283Sdfr unsigned long arg1, arg2; 34146283Sdfr char *arg_buf; 34246283Sdfr CORE_ADDR entry_point; 34346283Sdfr 34446283Sdfr if (exec_file == 0 || exec_bfd == 0) 34598944Sobrien error ("No executable file specified."); 34646283Sdfr 34746283Sdfr entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd); 34846283Sdfr 34998944Sobrien arm_rdi_kill (); 35046283Sdfr remove_breakpoints (); 35146283Sdfr init_wait_for_inferior (); 35246283Sdfr 35398944Sobrien len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10; 35446283Sdfr arg_buf = (char *) alloca (len); 35546283Sdfr arg_buf[0] = '\0'; 35646283Sdfr strcat (arg_buf, exec_file); 35746283Sdfr strcat (arg_buf, " "); 35846283Sdfr strcat (arg_buf, args); 35946283Sdfr 36098944Sobrien inferior_ptid = pid_to_ptid (42); 36198944Sobrien insert_breakpoints (); /* Needed to get correct instruction in cache */ 36246283Sdfr 36346283Sdfr if (env != NULL) 36446283Sdfr { 36546283Sdfr while (*env) 36646283Sdfr { 36746283Sdfr if (strncmp (*env, "MEMSIZE=", sizeof ("MEMSIZE=") - 1) == 0) 36846283Sdfr { 36946283Sdfr unsigned long top_of_memory; 37046283Sdfr char *end_of_num; 37146283Sdfr 37246283Sdfr /* Set up memory limit */ 37346283Sdfr top_of_memory = strtoul (*env + sizeof ("MEMSIZE=") - 1, 37446283Sdfr &end_of_num, 0); 37598944Sobrien printf_filtered ("Setting top-of-memory to 0x%lx\n", 37646283Sdfr top_of_memory); 37798944Sobrien 37846283Sdfr rslt = angel_RDI_info (RDIInfo_SetTopMem, &top_of_memory, &arg2); 379130803Smarcel if (rslt != RDIError_NoError) 38046283Sdfr { 38146283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 38246283Sdfr } 38346283Sdfr } 38446283Sdfr env++; 38546283Sdfr } 38646283Sdfr } 38746283Sdfr 38846283Sdfr arg1 = (unsigned long) arg_buf; 38998944Sobrien rslt = angel_RDI_info (RDISet_Cmdline, /* &arg1 */ (unsigned long *) arg_buf, &arg2); 390130803Smarcel if (rslt != RDIError_NoError) 39146283Sdfr { 39246283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 39346283Sdfr } 39446283Sdfr 39546283Sdfr proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0); 39646283Sdfr} 39746283Sdfr 39846283Sdfr/* This takes a program previously attached to and detaches it. After 39946283Sdfr this is done, GDB can be used to debug some other program. We 40046283Sdfr better not have left any breakpoints in the target program or it'll 40146283Sdfr die when it hits one. */ 40246283Sdfr 40346283Sdfrstatic void 40498944Sobrienarm_rdi_detach (char *args, int from_tty) 40546283Sdfr{ 40646283Sdfr pop_target (); 40746283Sdfr} 40846283Sdfr 40946283Sdfr/* Clean up connection to a remote debugger. */ 41046283Sdfr 41146283Sdfrstatic void 41298944Sobrienarm_rdi_close (int quitting) 41346283Sdfr{ 41446283Sdfr int rslt; 41546283Sdfr 41698944Sobrien if (!closed_already) 41746283Sdfr { 41846283Sdfr rslt = angel_RDI_close (); 419130803Smarcel if (rslt != RDIError_NoError) 42046283Sdfr { 42146283Sdfr printf_filtered ("RDI_close: %s\n", rdi_error_message (rslt)); 42246283Sdfr } 42346283Sdfr closed_already = 1; 42498944Sobrien inferior_ptid = null_ptid; 42598944Sobrien Adp_CloseDevice (); 42698944Sobrien generic_mourn_inferior (); 42746283Sdfr } 42846283Sdfr} 42946283Sdfr 43046283Sdfr/* Tell the remote machine to resume. */ 43146283Sdfr 43246283Sdfrstatic void 43398944Sobrienarm_rdi_resume (ptid_t ptid, int step, enum target_signal siggnal) 43446283Sdfr{ 43546283Sdfr int rslt; 43646283Sdfr PointHandle point; 43746283Sdfr 43898944Sobrien if (0 /* turn on when hardware supports single-stepping */ ) 43946283Sdfr { 44046283Sdfr rslt = angel_RDI_step (1, &point); 441130803Smarcel if (rslt != RDIError_NoError) 442130803Smarcel printf_filtered ("RDI_step: %s\n", rdi_error_message (rslt)); 44346283Sdfr } 44446283Sdfr else 44546283Sdfr { 44646283Sdfr char handle[4]; 447130803Smarcel CORE_ADDR pc = 0; 44846283Sdfr 44946283Sdfr if (step) 45046283Sdfr { 45198944Sobrien pc = read_register (ARM_PC_REGNUM); 45246283Sdfr pc = arm_get_next_pc (pc); 45346283Sdfr arm_rdi_insert_breakpoint (pc, handle); 45446283Sdfr } 455130803Smarcel 45646283Sdfr execute_status = rslt = angel_RDI_execute (&point); 457130803Smarcel if (rslt != RDIError_NoError && rslt != RDIError_BreakpointReached) 458130803Smarcel printf_filtered ("RDI_execute: %s\n", rdi_error_message (rslt)); 459130803Smarcel 46046283Sdfr if (step) 461130803Smarcel arm_rdi_remove_breakpoint (pc, handle); 46246283Sdfr } 46346283Sdfr} 46446283Sdfr 46546283Sdfr/* Wait until the remote machine stops, then return, storing status in 46646283Sdfr STATUS just as `wait' would. Returns "pid" (though it's not clear 46746283Sdfr what, if anything, that means in the case of this target). */ 46846283Sdfr 46998944Sobrienstatic ptid_t 47098944Sobrienarm_rdi_wait (ptid_t ptid, struct target_waitstatus *status) 47146283Sdfr{ 47246283Sdfr status->kind = (execute_status == RDIError_NoError ? 47398944Sobrien TARGET_WAITKIND_EXITED : TARGET_WAITKIND_STOPPED); 47446283Sdfr 47546283Sdfr /* convert stopped code from target into right signal */ 47646283Sdfr status->value.sig = rdi_error_signal (execute_status); 47746283Sdfr 47898944Sobrien return inferior_ptid; 47946283Sdfr} 48046283Sdfr 48146283Sdfr/* Read the remote registers into the block REGS. */ 48246283Sdfr 48346283Sdfrstatic void 48498944Sobrienarm_rdi_fetch_registers (int regno) 48546283Sdfr{ 48646283Sdfr int rslt, rdi_regmask; 48746283Sdfr unsigned long rawreg, rawregs[32]; 48846283Sdfr char cookedreg[4]; 48946283Sdfr 49098944Sobrien if (regno == -1) 49146283Sdfr { 49246283Sdfr rslt = angel_RDI_CPUread (255, 0x27fff, rawregs); 493130803Smarcel if (rslt != RDIError_NoError) 49446283Sdfr { 49546283Sdfr printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt)); 49646283Sdfr } 49746283Sdfr 49846283Sdfr for (regno = 0; regno < 15; regno++) 49946283Sdfr { 50046283Sdfr store_unsigned_integer (cookedreg, 4, rawregs[regno]); 50146283Sdfr supply_register (regno, (char *) cookedreg); 50246283Sdfr } 50346283Sdfr store_unsigned_integer (cookedreg, 4, rawregs[15]); 50498944Sobrien supply_register (ARM_PS_REGNUM, (char *) cookedreg); 50598944Sobrien arm_rdi_fetch_registers (ARM_PC_REGNUM); 50646283Sdfr } 50746283Sdfr else 50846283Sdfr { 50998944Sobrien if (regno == ARM_PC_REGNUM) 51046283Sdfr rdi_regmask = RDIReg_PC; 51198944Sobrien else if (regno == ARM_PS_REGNUM) 51246283Sdfr rdi_regmask = RDIReg_CPSR; 51346283Sdfr else if (regno < 0 || regno > 15) 51446283Sdfr { 51546283Sdfr rawreg = 0; 51646283Sdfr supply_register (regno, (char *) &rawreg); 51746283Sdfr return; 51846283Sdfr } 51946283Sdfr else 52046283Sdfr rdi_regmask = 1 << regno; 52146283Sdfr 52246283Sdfr rslt = angel_RDI_CPUread (255, rdi_regmask, &rawreg); 523130803Smarcel if (rslt != RDIError_NoError) 52446283Sdfr { 52546283Sdfr printf_filtered ("RDI_CPUread: %s\n", rdi_error_message (rslt)); 52646283Sdfr } 52746283Sdfr store_unsigned_integer (cookedreg, 4, rawreg); 52846283Sdfr supply_register (regno, (char *) cookedreg); 52946283Sdfr } 53046283Sdfr} 53146283Sdfr 53298944Sobrienstatic void 53398944Sobrienarm_rdi_prepare_to_store (void) 53446283Sdfr{ 53546283Sdfr /* Nothing to do. */ 53646283Sdfr} 53746283Sdfr 53846283Sdfr/* Store register REGNO, or all registers if REGNO == -1, from the contents 53946283Sdfr of REGISTERS. FIXME: ignores errors. */ 54046283Sdfr 54146283Sdfrstatic void 54298944Sobrienarm_rdi_store_registers (int regno) 54346283Sdfr{ 54446283Sdfr int rslt, rdi_regmask; 54546283Sdfr 54646283Sdfr /* These need to be able to take 'floating point register' contents */ 54746283Sdfr unsigned long rawreg[3], rawerreg[3]; 54846283Sdfr 54998944Sobrien if (regno == -1) 55046283Sdfr { 55146283Sdfr for (regno = 0; regno < NUM_REGS; regno++) 55246283Sdfr arm_rdi_store_registers (regno); 55346283Sdfr } 55446283Sdfr else 55546283Sdfr { 556130803Smarcel deprecated_read_register_gen (regno, (char *) rawreg); 55746283Sdfr /* RDI manipulates data in host byte order, so convert now. */ 55846283Sdfr store_unsigned_integer (rawerreg, 4, rawreg[0]); 55946283Sdfr 56098944Sobrien if (regno == ARM_PC_REGNUM) 56146283Sdfr rdi_regmask = RDIReg_PC; 56298944Sobrien else if (regno == ARM_PS_REGNUM) 56346283Sdfr rdi_regmask = RDIReg_CPSR; 56446283Sdfr else if (regno < 0 || regno > 15) 56546283Sdfr return; 56646283Sdfr else 56746283Sdfr rdi_regmask = 1 << regno; 56846283Sdfr 56946283Sdfr rslt = angel_RDI_CPUwrite (255, rdi_regmask, rawerreg); 570130803Smarcel if (rslt != RDIError_NoError) 57146283Sdfr { 57246283Sdfr printf_filtered ("RDI_CPUwrite: %s\n", rdi_error_message (rslt)); 57346283Sdfr } 57446283Sdfr } 57546283Sdfr} 57646283Sdfr 57746283Sdfr/* Read or write LEN bytes from inferior memory at MEMADDR, 57846283Sdfr transferring to or from debugger address MYADDR. Write to inferior 57946283Sdfr if SHOULD_WRITE is nonzero. Returns length of data written or 58098944Sobrien read; 0 for error. TARGET is unused. */ 58146283Sdfr 58246283Sdfrstatic int 58398944Sobrienarm_rdi_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, 58498944Sobrien int should_write, struct mem_attrib *attrib, 58598944Sobrien struct target_ops *target) 58646283Sdfr{ 58746283Sdfr int rslt, i; 58846283Sdfr 58946283Sdfr if (should_write) 59046283Sdfr { 59146283Sdfr rslt = angel_RDI_write (myaddr, memaddr, &len); 592130803Smarcel if (rslt != RDIError_NoError) 59346283Sdfr { 59446283Sdfr printf_filtered ("RDI_write: %s\n", rdi_error_message (rslt)); 59546283Sdfr } 59646283Sdfr } 59798944Sobrien else 59846283Sdfr { 59946283Sdfr rslt = angel_RDI_read (memaddr, myaddr, &len); 600130803Smarcel if (rslt != RDIError_NoError) 60146283Sdfr { 60246283Sdfr printf_filtered ("RDI_read: %s\n", rdi_error_message (rslt)); 60346283Sdfr len = 0; 60446283Sdfr } 60546283Sdfr } 60646283Sdfr return len; 60746283Sdfr} 60846283Sdfr 60946283Sdfr/* Display random info collected from the target. */ 61046283Sdfr 61146283Sdfrstatic void 61298944Sobrienarm_rdi_files_info (struct target_ops *ignore) 61346283Sdfr{ 61446283Sdfr char *file = "nothing"; 61546283Sdfr int rslt; 61646283Sdfr unsigned long arg1, arg2; 61746283Sdfr 61846283Sdfr rslt = angel_RDI_info (RDIInfo_Target, &arg1, &arg2); 619130803Smarcel if (rslt != RDIError_NoError) 62046283Sdfr { 62146283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 62246283Sdfr } 62346283Sdfr if (arg1 & (1 << 15)) 62446283Sdfr printf_filtered ("Target supports Thumb code.\n"); 62546283Sdfr if (arg1 & (1 << 14)) 62646283Sdfr printf_filtered ("Target can do profiling.\n"); 62746283Sdfr if (arg1 & (1 << 4)) 62846283Sdfr printf_filtered ("Target is real hardware.\n"); 62998944Sobrien 63046283Sdfr rslt = angel_RDI_info (RDIInfo_Step, &arg1, &arg2); 631130803Smarcel if (rslt != RDIError_NoError) 63246283Sdfr { 63346283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 63446283Sdfr } 63546283Sdfr printf_filtered ("Target can%s single-step.\n", (arg1 & 0x4 ? "" : "not")); 63646283Sdfr 63746283Sdfr rslt = angel_RDI_info (RDIInfo_Icebreaker, &arg1, &arg2); 638130803Smarcel if (rslt != RDIError_NoError) 63946283Sdfr { 64046283Sdfr printf_filtered ("RDI_info: %s\n", rdi_error_message (rslt)); 64146283Sdfr } 64246283Sdfr else 64346283Sdfr printf_filtered ("Target includes an EmbeddedICE.\n"); 64446283Sdfr} 64546283Sdfr 64646283Sdfrstatic void 64798944Sobrienarm_rdi_kill (void) 64846283Sdfr{ 64946283Sdfr int rslt; 65046283Sdfr 65146283Sdfr rslt = angel_RDI_open (1, &gdb_config, NULL, NULL); 652130803Smarcel if (rslt != RDIError_NoError) 65346283Sdfr { 65446283Sdfr printf_filtered ("RDI_open: %s\n", rdi_error_message (rslt)); 65546283Sdfr } 65646283Sdfr} 65746283Sdfr 65846283Sdfrstatic void 65998944Sobrienarm_rdi_mourn_inferior (void) 66046283Sdfr{ 66198944Sobrien /* We remove the inserted breakpoints in case the user wants to 66298944Sobrien issue another target and load commands to rerun his application; 66398944Sobrien This is something that wouldn't work on a native target, for instance, 66498944Sobrien as the process goes away when the inferior exits, but it works with 66598944Sobrien some remote targets like this one. That is why this is done here. */ 66698944Sobrien remove_breakpoints(); 66746283Sdfr unpush_target (&arm_rdi_ops); 66846283Sdfr generic_mourn_inferior (); 66946283Sdfr} 67046283Sdfr 67146283Sdfr/* While the RDI library keeps track of its own breakpoints, we need 67246283Sdfr to remember "handles" so that we can delete them later. Since 67346283Sdfr breakpoints get used for stepping, be careful not to leak memory 67446283Sdfr here. */ 67546283Sdfr 67646283Sdfrstatic int 67798944Sobrienarm_rdi_insert_breakpoint (CORE_ADDR addr, char *contents_cache) 67846283Sdfr{ 67946283Sdfr int rslt; 68046283Sdfr PointHandle point; 68146283Sdfr struct local_bp_list_entry *entry; 68246283Sdfr int type = RDIPoint_EQ; 68346283Sdfr 68446283Sdfr if (arm_pc_is_thumb (addr) || arm_pc_is_thumb_dummy (addr)) 68546283Sdfr type |= RDIPoint_16Bit; 68646283Sdfr rslt = angel_RDI_setbreak (addr, type, 0, &point); 687130803Smarcel if (rslt != RDIError_NoError) 68846283Sdfr { 68946283Sdfr printf_filtered ("RDI_setbreak: %s\n", rdi_error_message (rslt)); 69046283Sdfr } 69146283Sdfr entry = 69246283Sdfr (struct local_bp_list_entry *) xmalloc (sizeof (struct local_bp_list_entry)); 69346283Sdfr entry->addr = addr; 69446283Sdfr entry->point = point; 69546283Sdfr entry->next = local_bp_list; 69646283Sdfr local_bp_list = entry; 69746283Sdfr return rslt; 69846283Sdfr} 69946283Sdfr 70046283Sdfrstatic int 70198944Sobrienarm_rdi_remove_breakpoint (CORE_ADDR addr, char *contents_cache) 70246283Sdfr{ 70346283Sdfr int rslt; 70446283Sdfr PointHandle point; 705130803Smarcel struct local_bp_list_entry **entryp, *dead; 70646283Sdfr 707130803Smarcel for (entryp = &local_bp_list; *entryp != NULL; entryp = &(*entryp)->next) 708130803Smarcel if ((*entryp)->addr == addr) 709130803Smarcel break; 710130803Smarcel 711130803Smarcel if (*entryp) 71246283Sdfr { 713130803Smarcel dead = *entryp; 714130803Smarcel rslt = angel_RDI_clearbreak (dead->point); 715130803Smarcel if (rslt != RDIError_NoError) 716130803Smarcel printf_filtered ("RDI_clearbreak: %s\n", rdi_error_message (rslt)); 717130803Smarcel 71846283Sdfr /* Delete the breakpoint entry locally. */ 719130803Smarcel *entryp = dead->next; 720130803Smarcel xfree (dead); 72146283Sdfr } 722130803Smarcel 72346283Sdfr return 0; 72446283Sdfr} 725130803Smarcel 72646283Sdfr 72746283Sdfrstatic char * 72898944Sobrienrdi_error_message (int err) 72946283Sdfr{ 73046283Sdfr switch (err) 73146283Sdfr { 73298944Sobrien case RDIError_NoError: 73346283Sdfr return "no error"; 73446283Sdfr case RDIError_Reset: 73546283Sdfr return "debuggee reset"; 73646283Sdfr case RDIError_UndefinedInstruction: 73746283Sdfr return "undefined instruction"; 73846283Sdfr case RDIError_SoftwareInterrupt: 73946283Sdfr return "SWI trapped"; 74046283Sdfr case RDIError_PrefetchAbort: 74146283Sdfr return "prefetch abort, execution ran into unmapped memory?"; 74246283Sdfr case RDIError_DataAbort: 74346283Sdfr return "data abort, no memory at specified address?"; 74446283Sdfr case RDIError_AddressException: 74546283Sdfr return "address exception, access >26bit in 26bit mode"; 74646283Sdfr case RDIError_IRQ: 74746283Sdfr return "IRQ, interrupt trapped"; 74846283Sdfr case RDIError_FIQ: 74946283Sdfr return "FIQ, fast interrupt trapped"; 75046283Sdfr case RDIError_Error: 75146283Sdfr return "a miscellaneous type of error"; 75246283Sdfr case RDIError_BranchThrough0: 75346283Sdfr return "branch through location 0"; 75446283Sdfr case RDIError_NotInitialised: 75546283Sdfr return "internal error, RDI_open not called first"; 75646283Sdfr case RDIError_UnableToInitialise: 75746283Sdfr return "internal error, target world is broken"; 75846283Sdfr case RDIError_WrongByteSex: 75946283Sdfr return "See Operator: WrongByteSex"; 76046283Sdfr case RDIError_UnableToTerminate: 76146283Sdfr return "See Operator: Unable to Terminate"; 76246283Sdfr case RDIError_BadInstruction: 76346283Sdfr return "bad instruction, illegal to execute this instruction"; 76446283Sdfr case RDIError_IllegalInstruction: 76546283Sdfr return "illegal instruction, the effect of executing it is undefined"; 76646283Sdfr case RDIError_BadCPUStateSetting: 76746283Sdfr return "internal error, tried to set SPSR of user mode"; 76846283Sdfr case RDIError_UnknownCoPro: 76946283Sdfr return "unknown co-processor"; 77046283Sdfr case RDIError_UnknownCoProState: 77146283Sdfr return "cannot execute co-processor request"; 77246283Sdfr case RDIError_BadCoProState: 77346283Sdfr return "recognizably broken co-processor request"; 77446283Sdfr case RDIError_BadPointType: 77546283Sdfr return "internal error, bad point yype"; 77646283Sdfr case RDIError_UnimplementedType: 77746283Sdfr return "internal error, unimplemented type"; 77846283Sdfr case RDIError_BadPointSize: 77946283Sdfr return "internal error, bad point size"; 78046283Sdfr case RDIError_UnimplementedSize: 78146283Sdfr return "internal error, unimplemented size"; 78246283Sdfr case RDIError_NoMorePoints: 78346283Sdfr return "last break/watch point was used"; 78446283Sdfr case RDIError_BreakpointReached: 78546283Sdfr return "breakpoint reached"; 78646283Sdfr case RDIError_WatchpointAccessed: 78746283Sdfr return "watchpoint accessed"; 78846283Sdfr case RDIError_NoSuchPoint: 78946283Sdfr return "attempted to clear non-existent break/watch point"; 79046283Sdfr case RDIError_ProgramFinishedInStep: 79146283Sdfr return "end of the program reached while stepping"; 79246283Sdfr case RDIError_UserInterrupt: 79346283Sdfr return "you pressed Escape"; 79446283Sdfr case RDIError_CantSetPoint: 79546283Sdfr return "no more break/watch points available"; 79646283Sdfr case RDIError_IncompatibleRDILevels: 79746283Sdfr return "incompatible RDI levels"; 79846283Sdfr case RDIError_LittleEndian: 79946283Sdfr return "debuggee is little endian"; 80046283Sdfr case RDIError_BigEndian: 80146283Sdfr return "debuggee is big endian"; 80246283Sdfr case RDIError_SoftInitialiseError: 80346283Sdfr return "recoverable error in RDI initialization"; 80446283Sdfr case RDIError_InsufficientPrivilege: 80546283Sdfr return "internal error, supervisor state not accessible to monitor"; 80646283Sdfr case RDIError_UnimplementedMessage: 80746283Sdfr return "internal error, unimplemented message"; 80846283Sdfr case RDIError_UndefinedMessage: 80946283Sdfr return "internal error, undefined message"; 81046283Sdfr default: 81198944Sobrien return "undefined error message, should reset target"; 81246283Sdfr } 81346283Sdfr} 81446283Sdfr 81546283Sdfr/* Convert the ARM error messages to signals that GDB knows about. */ 81646283Sdfr 81746283Sdfrstatic enum target_signal 81898944Sobrienrdi_error_signal (int err) 81946283Sdfr{ 82046283Sdfr switch (err) 82146283Sdfr { 82246283Sdfr case RDIError_NoError: 82346283Sdfr return 0; 82446283Sdfr case RDIError_Reset: 82598944Sobrien return TARGET_SIGNAL_TERM; /* ??? */ 82646283Sdfr case RDIError_UndefinedInstruction: 82746283Sdfr return TARGET_SIGNAL_ILL; 82846283Sdfr case RDIError_SoftwareInterrupt: 82946283Sdfr case RDIError_PrefetchAbort: 83046283Sdfr case RDIError_DataAbort: 83146283Sdfr return TARGET_SIGNAL_TRAP; 83246283Sdfr case RDIError_AddressException: 83346283Sdfr return TARGET_SIGNAL_SEGV; 83446283Sdfr case RDIError_IRQ: 83546283Sdfr case RDIError_FIQ: 83646283Sdfr return TARGET_SIGNAL_TRAP; 83746283Sdfr case RDIError_Error: 83846283Sdfr return TARGET_SIGNAL_TERM; 83946283Sdfr case RDIError_BranchThrough0: 84046283Sdfr return TARGET_SIGNAL_TRAP; 84146283Sdfr case RDIError_NotInitialised: 84246283Sdfr case RDIError_UnableToInitialise: 84346283Sdfr case RDIError_WrongByteSex: 84446283Sdfr case RDIError_UnableToTerminate: 84546283Sdfr return TARGET_SIGNAL_UNKNOWN; 84646283Sdfr case RDIError_BadInstruction: 84746283Sdfr case RDIError_IllegalInstruction: 84846283Sdfr return TARGET_SIGNAL_ILL; 84946283Sdfr case RDIError_BadCPUStateSetting: 85046283Sdfr case RDIError_UnknownCoPro: 85146283Sdfr case RDIError_UnknownCoProState: 85246283Sdfr case RDIError_BadCoProState: 85346283Sdfr case RDIError_BadPointType: 85446283Sdfr case RDIError_UnimplementedType: 85546283Sdfr case RDIError_BadPointSize: 85646283Sdfr case RDIError_UnimplementedSize: 85746283Sdfr case RDIError_NoMorePoints: 85846283Sdfr return TARGET_SIGNAL_UNKNOWN; 85946283Sdfr case RDIError_BreakpointReached: 86046283Sdfr case RDIError_WatchpointAccessed: 86146283Sdfr return TARGET_SIGNAL_TRAP; 86246283Sdfr case RDIError_NoSuchPoint: 86346283Sdfr case RDIError_ProgramFinishedInStep: 86446283Sdfr return TARGET_SIGNAL_UNKNOWN; 86546283Sdfr case RDIError_UserInterrupt: 86646283Sdfr return TARGET_SIGNAL_INT; 86746283Sdfr case RDIError_IncompatibleRDILevels: 86846283Sdfr case RDIError_LittleEndian: 86946283Sdfr case RDIError_BigEndian: 87046283Sdfr case RDIError_SoftInitialiseError: 87146283Sdfr case RDIError_InsufficientPrivilege: 87246283Sdfr case RDIError_UnimplementedMessage: 87346283Sdfr case RDIError_UndefinedMessage: 87446283Sdfr default: 87598944Sobrien return TARGET_SIGNAL_UNKNOWN; 87646283Sdfr } 87746283Sdfr} 87898944Sobrien 87998944Sobrienstatic void 88098944Sobrienarm_rdi_stop(void) 88198944Sobrien{ 88298944Sobrien angel_RDI_stop_request(); 88398944Sobrien} 88498944Sobrien 88546283Sdfr 88646283Sdfr/* Define the target operations structure. */ 88746283Sdfr 88846283Sdfrstatic void 88998944Sobrieninit_rdi_ops (void) 89046283Sdfr{ 89198944Sobrien arm_rdi_ops.to_shortname = "rdi"; 89246283Sdfr arm_rdi_ops.to_longname = "ARM RDI"; 89346283Sdfr arm_rdi_ops.to_doc = "Use a remote ARM-based computer; via the RDI library.\n\ 89498944SobrienSpecify the serial device it is connected to (e.g. /dev/ttya)."; 89598944Sobrien arm_rdi_ops.to_open = arm_rdi_open; 89698944Sobrien arm_rdi_ops.to_close = arm_rdi_close; 89798944Sobrien arm_rdi_ops.to_detach = arm_rdi_detach; 89898944Sobrien arm_rdi_ops.to_resume = arm_rdi_resume; 89998944Sobrien arm_rdi_ops.to_wait = arm_rdi_wait; 90098944Sobrien arm_rdi_ops.to_stop = arm_rdi_stop; 90146283Sdfr arm_rdi_ops.to_fetch_registers = arm_rdi_fetch_registers; 90246283Sdfr arm_rdi_ops.to_store_registers = arm_rdi_store_registers; 90346283Sdfr arm_rdi_ops.to_prepare_to_store = arm_rdi_prepare_to_store; 90446283Sdfr arm_rdi_ops.to_xfer_memory = arm_rdi_xfer_memory; 90546283Sdfr arm_rdi_ops.to_files_info = arm_rdi_files_info; 90646283Sdfr arm_rdi_ops.to_insert_breakpoint = arm_rdi_insert_breakpoint; 90798944Sobrien arm_rdi_ops.to_remove_breakpoint = arm_rdi_remove_breakpoint; 90898944Sobrien arm_rdi_ops.to_kill = arm_rdi_kill; 90998944Sobrien arm_rdi_ops.to_load = generic_load; 91046283Sdfr arm_rdi_ops.to_create_inferior = arm_rdi_create_inferior; 91146283Sdfr arm_rdi_ops.to_mourn_inferior = arm_rdi_mourn_inferior; 91246283Sdfr arm_rdi_ops.to_stratum = process_stratum; 91398944Sobrien arm_rdi_ops.to_has_all_memory = 1; 91498944Sobrien arm_rdi_ops.to_has_memory = 1; 91598944Sobrien arm_rdi_ops.to_has_stack = 1; 91698944Sobrien arm_rdi_ops.to_has_registers = 1; 91798944Sobrien arm_rdi_ops.to_has_execution = 1; 91898944Sobrien arm_rdi_ops.to_magic = OPS_MAGIC; 91946283Sdfr} 92046283Sdfr 92198944Sobrienstatic void 92298944Sobrienrdilogfile_command (char *arg, int from_tty) 92398944Sobrien{ 92498944Sobrien if (!arg || strlen (arg) == 0) 92598944Sobrien { 92698944Sobrien printf_filtered ("rdi log file is '%s'\n", log_filename); 92798944Sobrien return; 92898944Sobrien } 92998944Sobrien 93098944Sobrien if (log_filename) 93198944Sobrien xfree (log_filename); 93298944Sobrien 93398944Sobrien log_filename = xstrdup (arg); 93498944Sobrien 93598944Sobrien Adp_SetLogfile (log_filename); 93698944Sobrien} 93798944Sobrien 93898944Sobrienstatic void 93998944Sobrienrdilogenable_command (char *args, int from_tty) 94098944Sobrien{ 94198944Sobrien if (!args || strlen (args) == 0) 94298944Sobrien { 94398944Sobrien printf_filtered ("rdi log is %s\n", log_enable ? "enabled" : "disabled"); 94498944Sobrien return; 94598944Sobrien } 94698944Sobrien 94798944Sobrien if (!strcasecmp (args, "1") || 94898944Sobrien !strcasecmp (args, "y") || 94998944Sobrien !strcasecmp (args, "yes") || 95098944Sobrien !strcasecmp (args, "on") || 95198944Sobrien !strcasecmp (args, "t") || 95298944Sobrien !strcasecmp (args, "true")) 95398944Sobrien Adp_SetLogEnable (log_enable = 1); 95498944Sobrien else if (!strcasecmp (args, "0") || 95598944Sobrien !strcasecmp (args, "n") || 95698944Sobrien !strcasecmp (args, "no") || 95798944Sobrien !strcasecmp (args, "off") || 95898944Sobrien !strcasecmp (args, "f") || 95998944Sobrien !strcasecmp (args, "false")) 96098944Sobrien Adp_SetLogEnable (log_enable = 0); 96198944Sobrien else 96298944Sobrien printf_filtered ("rdilogenable: unrecognized argument '%s'\n" 96398944Sobrien " try y or n\n", args); 96498944Sobrien} 96598944Sobrien 966130803Smarcelextern initialize_file_ftype _initialize_remote_rdi; /* -Wmissing-prototypes */ 967130803Smarcel 96846283Sdfrvoid 96998944Sobrien_initialize_remote_rdi (void) 97046283Sdfr{ 97198944Sobrien struct cmd_list_element *c; 97298944Sobrien 97398944Sobrien init_rdi_ops (); 97446283Sdfr add_target (&arm_rdi_ops); 97598944Sobrien 97698944Sobrien log_filename = xstrdup ("rdi.log"); 97798944Sobrien Adp_SetLogfile (log_filename); 97898944Sobrien Adp_SetLogEnable (log_enable); 97998944Sobrien 98098944Sobrien c = add_cmd ("rdilogfile", class_maintenance, 98198944Sobrien rdilogfile_command, 982130803Smarcel "Set filename for ADP packet log.\n" 983130803Smarcel "This file is used to log Angel Debugger Protocol packets.\n" 984130803Smarcel "With a single argument, sets the logfile name to that value.\n" 985130803Smarcel "Without an argument, shows the current logfile name.\n" 986130803Smarcel "See also: rdilogenable\n", 987130803Smarcel &maintenancelist); 988130803Smarcel set_cmd_completer (c, filename_completer); 98998944Sobrien 99098944Sobrien add_cmd ("rdilogenable", class_maintenance, 99198944Sobrien rdilogenable_command, 992130803Smarcel "Set enable logging of ADP packets.\n" 993130803Smarcel "This will log ADP packets exchanged between gdb and the\n" 994130803Smarcel "rdi target device.\n" 995130803Smarcel "An argument of 1, t, true, y or yes will enable.\n" 996130803Smarcel "An argument of 0, f, false, n or no will disabled.\n" 997130803Smarcel "Withough an argument, it will display current state.\n", 99898944Sobrien &maintenancelist); 99998944Sobrien 1000130803Smarcel add_setshow_boolean_cmd 1001130803Smarcel ("rdiromatzero", no_class, &rom_at_zero, 1002130803Smarcel "Set target has ROM at addr 0.\n" 1003130803Smarcel "A true value disables vector catching, false enables vector catching.\n" 1004130803Smarcel "This is evaluated at the time the 'target rdi' command is executed\n", 1005130803Smarcel "Show if target has ROM at addr 0.\n", 1006130803Smarcel NULL, NULL, 1007130803Smarcel &setlist, &showlist); 100898944Sobrien 1009130803Smarcel add_setshow_boolean_cmd 1010130803Smarcel ("rdiheartbeat", no_class, &rdi_heartbeat, 1011130803Smarcel "Set enable for ADP heartbeat packets.\n" 1012130803Smarcel "I don't know why you would want this. If you enable them,\n" 1013130803Smarcel "it will confuse ARM and EPI JTAG interface boxes as well\n" 1014130803Smarcel "as the Angel Monitor.\n", 1015130803Smarcel "Show enable for ADP heartbeat packets.\n", 1016130803Smarcel NULL, NULL, 1017130803Smarcel &setlist, &showlist); 101846283Sdfr} 101946283Sdfr 102046283Sdfr/* A little dummy to make linking with the library succeed. */ 102146283Sdfr 1022130803Smarcelvoid 1023130803SmarcelFail (const char *ignored, ...) 102498944Sobrien{ 1025130803Smarcel 102698944Sobrien} 1027