diff options
Diffstat (limited to 'gdb/remote-rdp.c')
-rw-r--r-- | gdb/remote-rdp.c | 217 |
1 files changed, 209 insertions, 8 deletions
diff --git a/gdb/remote-rdp.c b/gdb/remote-rdp.c index 3cc4c4e..04a9473 100644 --- a/gdb/remote-rdp.c +++ b/gdb/remote-rdp.c @@ -54,6 +54,7 @@ #ifdef HAVE_UNISTD_H #include <unistd.h> #endif +#include "gdbcore.h" extern struct target_ops remote_rdp_ops; @@ -138,6 +139,16 @@ ds; #define RDP_INFO_ABOUT_BREAK_THREAD_BREAK (1<<9) #define RDP_INFO_ABOUT_BREAK_THREAD_WATCH (1<<10) #define RDP_INFO_ABOUT_BREAK_COND (1<<11) +#define RDP_INFO_VECTOR_CATCH (0x180) +#define RDP_INFO_ICEBREAKER (7) +#define RDP_INFO_SET_CMDLINE (0x300) + +#define RDP_SELECT_CONFIG (0x16) +#define RDI_ConfigCPU 0 +#define RDI_ConfigSystem 1 +#define RDI_MatchAny 0 +#define RDI_MatchExactly 1 +#define RDI_MatchNoEarlier 2 #define RDP_RESET 0x7f @@ -157,6 +168,8 @@ ds; static int timeout = 2; +static char * commandline = NULL; + static int remote_rdp_xfer_inferior_memory PARAMS ((CORE_ADDR memaddr, char *myaddr, @@ -263,9 +276,39 @@ rdp_init (cold, tty) if (tty) printf_unfiltered ("Trying to connect at %d baud.\n", baudtry); + + /* + ** It seems necessary to reset an EmbeddedICE to get it going. + ** This has the side benefit of displaying the startup banner. + */ + if (cold) + { + put_byte (RDP_RESET); + while ((restype = SERIAL_READCHAR (io, 1)) > 0) + { + switch (restype) + { + case SERIAL_TIMEOUT: + break; + case RDP_RESET: + /* Sent at start of reset process: ignore */ + break; + default: + printf_unfiltered ("%c", isgraph (restype) ? restype : ' '); + break; + } + } + + if (restype == 0) + { + /* Got end-of-banner mark */ + printf_filtered ("\n"); + } + } + put_byte (RDP_OPEN); - put_byte (type | RDP_OPEN_TYPE_RETURN_SEX); + put_byte (type | RDP_OPEN_TYPE_RETURN_SEX ); put_word (0); while (!sync && (restype = SERIAL_READCHAR (io, 1)) > 0) @@ -300,6 +343,10 @@ rdp_init (cold, tty) case RDP_RES_VALUE: { int resval = SERIAL_READCHAR (io, 1); + + if (remote_debug) + printf_unfiltered ("[%02x]\n", resval); + switch (resval) { case SERIAL_TIMEOUT: @@ -384,9 +431,27 @@ send_rdp (char *template, va_alist) } break; case 'Z': - /* Check the result code, error if not zero */ - if (get_byte ()) - error ("Command garbled"); + /* Check the result code */ + switch (get_byte ()) + { + case 0: + /* Success */ + break; + case 253: + /* Target can't do it; never mind */ + printf_unfiltered ("RDP: Insufficient privilege\n"); + return; + case 254: + /* Target can't do it; never mind */ + printf_unfiltered ("RDP: Unimplemented message\n"); + return; + case 255: + error ("Command garbled"); + break; + default: + error ("Corrupt reply from target"); + break; + } break; case 'W': /* Read a word from the target */ @@ -652,6 +717,50 @@ rdp_execute_start () } +static void +rdp_set_command_line (command, args) + char * command; + char * args; +{ + /* + ** We could use RDP_INFO_SET_CMDLINE to send this, but EmbeddedICE systems + ** don't implement that, and get all confused at the unexpected text. + ** Instead, just keep a copy, and send it when the target does a SWI_GetEnv + */ + + if (commandline != NULL) + free (commandline); + + commandline = malloc (strlen (command) + strlen (args) + 2); + if (commandline != NULL) + { + strcpy (commandline, command); + strcat (commandline, " "); + strcat (commandline, args); + } +} + +static void +rdp_catch_vectors () +{ + /* + ** We want the target monitor to intercept the abort vectors + ** i.e. stop the program if any of these are used. + */ + send_rdp ("bww-SZ", RDP_INFO, RDP_INFO_VECTOR_CATCH, + /* + ** Specify a bitmask including + ** the reset vector + ** the undefined instruction vector + ** the prefetch abort vector + ** the data abort vector + ** the address exception vector + */ + (1<<0)|(1<<1)|(1<<3)|(1<<4)|(1<<5) + ); +} + + #define a_byte 1 #define a_word 2 @@ -786,6 +895,22 @@ exec_swi (swi, args) args->n = callback->isatty (callback, args->n); return 1; + case SWI_GetEnv: + if (commandline != NULL) + { + int len = strlen (commandline); + if (len > 255) + { + len = 255; + commandline [255]='\0'; + } + remote_rdp_xfer_inferior_memory (args[0].n, + commandline, len+1, 1, 0); + } + else + remote_rdp_xfer_inferior_memory (args[0].n, "", 1, 1, 0); + return 1; + default: return 0; } @@ -986,6 +1111,8 @@ remote_rdp_open (args, from_tty) char *args; int from_tty; { + int not_icebreaker; + if (!args) error_no_arg ("serial port device name"); @@ -1010,7 +1137,33 @@ remote_rdp_open (args, from_tty) rdp_info (); - push_target (&remote_rdp_ops); + /* Need to set up the vector interception state */ + rdp_catch_vectors(); + + /* + ** If it's an EmbeddedICE, we need to set the processor config. + ** Assume we can always have ARM7TDI... + */ + send_rdp ("bw-SB", RDP_INFO, RDP_INFO_ICEBREAKER, & not_icebreaker); + if (!not_icebreaker) + { + const char * CPU = "ARM7TDI"; + int ICEversion; + int len = strlen (CPU); + + send_rdp ("bbbbw-p-SWZ", + RDP_SELECT_CONFIG, + RDI_ConfigCPU, /* Aspect: set the CPU */ + len, /* The number of bytes in the name */ + RDI_MatchAny, /* We'll take whatever we get */ + 0, /* We'll take whatever version's there */ + CPU,len, + & ICEversion); + } + + /* command line initialised on 'run'*/ + + push_target (& remote_rdp_ops); callback->init (callback); flush_cached_frames (); @@ -1192,6 +1345,54 @@ remote_rdp_files_info (target) } +static void +remote_rdp_create_inferior (exec_file, allargs, env) + char * exec_file; + char * allargs; + char ** env; +{ + CORE_ADDR entry_point; + + if (exec_file == 0 || exec_bfd == 0) + error ("No exec file specified."); + + entry_point = (CORE_ADDR) bfd_get_start_address (exec_bfd); + + remote_rdp_kill (); + remove_breakpoints (); + init_wait_for_inferior (); + + /* This gives us a chance to set up the command line */ + rdp_set_command_line (exec_file, allargs); + + inferior_pid = 42; + insert_breakpoints (); /* Needed to get correct instruction in cache */ + + /* + ** RDP targets don't provide any facility to set the top of memory, + ** so we don't bother to look for MEMSIZE in the environment. + */ + + /* Let's go! */ + proceed (entry_point, TARGET_SIGNAL_DEFAULT, 0); +} + +/* Accept any stray run/attach commands */ +static int +remote_rdp_can_run() +{ + return 1; +} + +/* Attach doesn't need to do anything */ +static void +remote_rdp_attach(args, from_tty) + char * args; + int from_tty; +{ + return; +} + /* Define the target subroutine names */ struct target_ops remote_rdp_ops = @@ -1203,7 +1404,7 @@ struct target_ops remote_rdp_ops = "Use a remote ARM system which uses the ARM Remote Debugging Protocol", remote_rdp_open, /* to_open */ remote_rdp_close, /* to_close */ - NULL, /* to_attach */ + remote_rdp_attach, /* to_attach */ NULL, /* to_detach */ remote_rdp_resume, /* to_resume */ remote_rdp_wait, /* to_wait */ @@ -1222,9 +1423,9 @@ struct target_ops remote_rdp_ops = remote_rdp_kill, /* to_kill */ generic_load, /* to_load */ NULL, /* to_lookup_symbol */ - NULL, /* to_create_inferior */ + remote_rdp_create_inferior, /* to_create_inferior */ generic_mourn_inferior, /* to_mourn_inferior */ - 0, /* to_can_run */ + remote_rdp_can_run, /* to_can_run */ 0, /* to_notice_signals */ 0, /* to_thread_alive */ 0, /* to_stop */ |