-/* Remote target communications for the Macraigor Systems BDM Wiggler
+/* Target communications support for Macraigor Systems' On-Chip Debugging
Copyright 1996, 1997 Free Software Foundation, Inc.
This file is part of GDB.
/* Prototypes for local functions */
-static int ocd_write_bytes PARAMS ((CORE_ADDR memaddr,
- char *myaddr, int len));
-
static int ocd_read_bytes PARAMS ((CORE_ADDR memaddr,
char *myaddr, int len));
static void interrupt_query PARAMS ((void));
-static unsigned char * do_command PARAMS ((int cmd, int *statusp, int *lenp));
+static unsigned char * ocd_do_command PARAMS ((int cmd, int *statusp, int *lenp));
static void ocd_put_packet PARAMS ((unsigned char *packet, int pktlen));
other form of hairy serial connection, I would think 2 seconds would
be plenty. */
-/* Changed to allow option to set timeout value.
- was static int remote_timeout = 2; */
-extern int remote_timeout;
+/* FIXME: Change to allow option to set timeout value on a per target
+ basis.
+
+static int remote_timeout = 2;
/* Descriptor for I/O to remote machine. Initialize it to NULL so that
ocd_open knows that we don't have a file open when the program
case 0x1: s = "Unknown fault"; break;
case 0x2: s = "Power failed"; break;
case 0x3: s = "Cable disconnected"; break;
- case 0x4: s = "Couldn't enter BDM"; break;
+ case 0x4: s = "Couldn't enter OCD mode"; break;
case 0x5: s = "Target stuck in reset"; break;
- case 0x6: s = "Port not configured"; break;
+ case 0x6: s = "OCD hasn't been initialized"; break;
case 0x7: s = "Write verify failed"; break;
+ case 0x8: s = "Reg buff error (during MPC5xx fp reg read/write)"; break;
+ case 0x9: s = "Invalid CPU register access attempt failed"; break;
case 0x11: s = "Bus error"; break;
case 0x12: s = "Checksum error"; break;
case 0x13: s = "Illegal command"; break;
case 0x14: s = "Parameter error"; break;
case 0x15: s = "Internal error"; break;
- case 0x16: s = "Register buffer error"; break;
case 0x80: s = "Flash erase error"; break;
default:
sprintf (buf, "Unknown error code %d", error_code);
SERIAL_SEND_BREAK (ocd_desc); /* Wake up the wiggler */
- do_command (OCD_AYT, &status, &pktlen);
-
- p = do_command (OCD_GET_VERSION, &status, &pktlen);
-
- printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
- p[0], p[1], (p[2] << 16) | p[3]);
-
-#if 1
speed = 80; /* Divide clock by 4000 */
buf[0] = OCD_INIT;
if (error_code != 0)
ocd_error ("OCD_INIT:", error_code);
-#endif
+
+ ocd_do_command (OCD_AYT, &status, &pktlen);
+
+ p = ocd_do_command (OCD_GET_VERSION, &status, &pktlen);
+
+ printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
+ p[0], p[1], (p[2] << 16) | p[3]);
#if 0
/* Reset the target */
- do_command (OCD_RESET_RUN, &status, &pktlen);
-/* do_command (OCD_RESET, &status, &pktlen);*/
+ ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
+/* ocd_do_command (OCD_RESET, &status, &pktlen);*/
#endif
/* If processor is still running, stop it. */
ocd_stop ();
#if 1
+ /* When using a target box, we want to asynchronously return status when
+ target stops. The OCD_SET_CTL_FLAGS command is ignored by Wigglers.dll
+ when using a parallel Wiggler */
buf[0] = OCD_SET_CTL_FLAGS;
buf[1] = 0;
- buf[2] = 1; /* Asynchronously return status when target stops */
+ buf[2] = 1;
ocd_put_packet (buf, 3);
p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
select_frame (get_current_frame (), 0);
print_stack_frame (selected_frame, -1, 1);
+ buf[0] = OCD_LOG_FILE;
+ buf[1] = 3; /* close existing WIGGLERS.LOG */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ buf[0] = OCD_LOG_FILE;
+ buf[1] = 2; /* append to existing WIGGLERS.LOG */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
return 1;
}
enum ocd_target_type target_type;
struct target_ops *ops;
{
+ unsigned char buf[10], *p;
+ int status;
+ int pktlen;
+
if (name == 0)
error ("To open an OCD connection, you need to specify the\n\
device the OCD device is attached to (e.g. /dev/ttya).");
ocd_dcache = dcache_init (ocd_read_bytes, ocd_write_bytes);
- ocd_desc = SERIAL_OPEN (name);
- if (!ocd_desc)
- perror_with_name (name);
+ if (strncmp(name,"wiggler",7) == 0)
+ {
+ ocd_desc = SERIAL_OPEN ("ocd");
+ if (!ocd_desc)
+ perror_with_name (name);
+
+ buf[0] = OCD_LOG_FILE;
+ buf[1] = 1; /* open new or overwrite existing WIGGLERS.LOG */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+
+ buf[0] = OCD_SET_CONNECTION;
+ buf[1] = 0x01; /* atoi (name[11]); */
+ ocd_put_packet (buf, 2);
+ p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
+ }
+ else /* not using Wigglers.dll */
+ {
+ ocd_desc = SERIAL_OPEN (name);
+ if (!ocd_desc)
+ perror_with_name (name);
+ }
if (baud_rate != -1)
{
In particular, if the user quits, be sure to discard it
(we'd be in an inconsistent state otherwise). */
if (!catch_errors (ocd_start_remote, (char *)target_type,
- "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
- pop_target();
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ {
+ pop_target();
+ error ("Failed to connect to OCD.");
+ }
}
/* This takes a program previously attached to and detaches it. After
dcache_flush (ocd_dcache);
if (step)
- do_command (OCD_STEP, &last_run_status, &pktlen);
+ ocd_do_command (OCD_STEP, &last_run_status, &pktlen);
else
- do_command (OCD_RUN, &last_run_status, &pktlen);
+ ocd_do_command (OCD_RUN, &last_run_status, &pktlen);
}
\f
void
int status;
int pktlen;
- do_command (OCD_STOP, &status, &pktlen);
+ ocd_do_command (OCD_STOP, &status, &pktlen);
if (!(status & OCD_FLAG_BDM))
error ("Can't stop target via BDM");
ocd_wait ()
{
unsigned char *p;
- int error_code, status;
+ int error_code;
int pktlen;
+ char buf[1];
ocd_interrupt_flag = 0;
- /* Target may already be stopped by the time we get here. */
+ /* Target might already be stopped by the time we get here. */
+ /* If we aren't already stopped, we need to loop until we've dropped
+ back into BDM mode */
- if (!(last_run_status & OCD_FLAG_BDM))
+ while (!(last_run_status & OCD_FLAG_BDM))
{
- ofunc = (void (*)()) signal (SIGINT, ocd_interrupt);
-
+ buf[0] = OCD_AYT;
+ ocd_put_packet (buf, 1);
p = ocd_get_packet (OCD_AYT, &pktlen, -1);
+ ofunc = (void (*)()) signal (SIGINT, ocd_interrupt);
signal (SIGINT, ofunc);
if (pktlen < 2)
error ("Truncated response packet from OCD device");
- status = p[1];
+ last_run_status = p[1];
error_code = p[2];
if (error_code != 0)
ocd_error ("target_wait:", error_code);
- if (status & OCD_FLAG_PWF)
+ if (last_run_status & OCD_FLAG_PWF)
error ("OCD device lost VCC at BDM interface.");
- else if (status & OCD_FLAG_CABLE_DISC)
- error ("BDM cable appears to have been disconnected.");
-
- if (!(status & OCD_FLAG_BDM))
- error ("OCD device woke up, but wasn't stopped: 0x%x", status);
+ else if (last_run_status & OCD_FLAG_CABLE_DISC)
+ error ("OCD device cable appears to have been disconnected.");
}
if (ocd_interrupt_flag)
static int write_mem_command = OCD_WRITE_MEM;
-static int
+int
ocd_write_bytes (memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
unsigned char *packet_ptr;
unsigned char checksum;
- find_packet:
-
ch = readchar (timeout);
if (ch < 0)
error ("ocd_get_packet (readchar): %d", ch);
if (ch != 0x55)
- goto find_packet;
+ error ("ocd_get_packet (readchar): %d", ch);
/* Found the start of a packet */
case OCD_PROGRAM_FLASH: /* Write flash memory */
case OCD_EXIT_MON: /* Exit the flash programming monitor */
case OCD_ENTER_MON: /* Enter the flash programming monitor */
+ case OCD_LOG_FILE: /* Make Wigglers.dll save Wigglers.log */
+ case OCD_SET_CONNECTION: /* Set type of connection in Wigglers.dll */
len = 0;
break;
case OCD_GET_VERSION: /* Get Version */
len = 257;
break;
default:
- fprintf_filtered (gdb_stderr, "Unknown packet type 0x%x\n", ch);
- goto find_packet;
+ error ("ocd_get_packet: unknown packet type 0x%x\n", ch);
}
}
}
if (checksum != 0)
- goto find_packet;
+ error ("ocd_get_packet: bad packet checksum");
if (cmd != -1 && cmd != packet[0])
error ("Response phase error. Got 0x%x, expected 0x%x", packet[0], cmd);
following the error code. */
static unsigned char *
-do_command (cmd, statusp, lenp)
+ocd_do_command (cmd, statusp, lenp)
int cmd;
int *statusp;
int *lenp;
int status, error_code;
char errbuf[100];
+ unsigned char logbuf[100];
+ int logpktlen;
+
buf[0] = cmd;
ocd_put_packet (buf, 1); /* Send command */
p = ocd_get_packet (*buf, lenp, remote_timeout);
if (error_code != 0)
{
- sprintf (errbuf, "do_command (0x%x):", cmd);
+ sprintf (errbuf, "ocd_do_command (0x%x):", cmd);
ocd_error (errbuf, error_code);
}
*statusp = status;
+ logbuf[0] = OCD_LOG_FILE;
+ logbuf[1] = 3; /* close existing WIGGLERS.LOG */
+ ocd_put_packet (logbuf, 2);
+ ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
+
+ logbuf[0] = OCD_LOG_FILE;
+ logbuf[1] = 2; /* append to existing WIGGLERS.LOG */
+ ocd_put_packet (logbuf, 2);
+ ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
+
return p + 3;
}
\f
clear_symtab_users ();
}
+/* This should be defined for each target */
+/* But we want to be able to compile this file for some configurations
+ not yet supported fully */
+
+#define BDM_BREAKPOINT {0x0,0x0,0x0,0x0} /* For ppc 8xx */
+/* #define BDM_BREAKPOINT {0x4a,0xfa} /* BGND insn used for CPU32 */
+
/* BDM (at least on CPU32) uses a different breakpoint */
-static int
+int
ocd_insert_breakpoint (addr, contents_cache)
CORE_ADDR addr;
char *contents_cache;
{
- static char break_insn[] = {BDM_BREAKPOINT};
+ static char break_insn[] = BDM_BREAKPOINT;
int val;
- val = target_read_memory (addr, contents_cache, sizeof break_insn);
+ val = target_read_memory (addr, contents_cache, sizeof (break_insn));
if (val == 0)
- val = target_write_memory (addr, break_insn, sizeof break_insn);
+ val = target_write_memory (addr, break_insn, sizeof (break_insn));
+
+ return val;
+}
+
+int
+ocd_remove_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+{
+ static char break_insn[] = BDM_BREAKPOINT;
+ int val;
+
+ val = target_write_memory (addr, contents_cache, sizeof (break_insn));
return val;
}
if (!ocd_desc)
error ("Not connected to OCD device.");
- do_command (OCD_RESET, &status, &pktlen);
+ ocd_do_command (OCD_RESET, &status, &pktlen);
dcache_flush (ocd_dcache);
registers_changed ();
}
if (!ocd_desc)
error ("Not connected to OCD device.");
- do_command (OCD_RESET_RUN, &status, &pktlen);
+ ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
last_run_status = status;
clear_proceed_status ();
wait_for_inferior ();
/* old_chain = make_cleanup (flash_cleanup, 0);*/
- do_command (OCD_ENTER_MON, &status, &pktlen);
+ ocd_do_command (OCD_ENTER_MON, &status, &pktlen);
- do_command (OCD_ERASE_FLASH, &status, &pktlen);
+ ocd_do_command (OCD_ERASE_FLASH, &status, &pktlen);
write_mem_command = OCD_PROGRAM_FLASH;
store_registers_tmp = current_target.to_store_registers;
current_target.to_store_registers = store_registers_tmp;
write_mem_command = OCD_WRITE_MEM;
- do_command (OCD_EXIT_MON, &status, &pktlen);
+ ocd_do_command (OCD_EXIT_MON, &status, &pktlen);
/* discard_cleanups (old_chain);*/
}