aboutsummaryrefslogtreecommitdiff
path: root/gdb/ocd.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/ocd.c')
-rw-r--r--gdb/ocd.c1172
1 files changed, 0 insertions, 1172 deletions
diff --git a/gdb/ocd.c b/gdb/ocd.c
deleted file mode 100644
index f529900..0000000
--- a/gdb/ocd.c
+++ /dev/null
@@ -1,1172 +0,0 @@
-/* Target communications support for Macraigor Systems' On-Chip Debugging
-
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2006, 2007
- Free Software Foundation, Inc.
-
- This file is part of GDB.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "gdb_string.h"
-#include <fcntl.h>
-#include "frame.h"
-#include "inferior.h"
-#include "bfd.h"
-#include "symfile.h"
-#include "target.h"
-#include "exceptions.h"
-#include "gdbcmd.h"
-#include "objfiles.h"
-#include "gdb-stabs.h"
-#include <sys/types.h>
-#include <signal.h>
-#include "serial.h"
-#include "ocd.h"
-#include "regcache.h"
-
-/* Prototypes for local functions */
-
-static int ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len);
-
-static int ocd_start_remote (void *dummy);
-
-static int readchar (int timeout);
-
-static void ocd_interrupt (int signo);
-
-static void ocd_interrupt_twice (int signo);
-
-static void interrupt_query (void);
-
-static unsigned char *ocd_do_command (int cmd, int *statusp, int *lenp);
-
-static void ocd_put_packet (unsigned char *packet, int pktlen);
-
-static unsigned char *ocd_get_packet (int cmd, int *pktlen, int timeout);
-
-static struct target_ops *current_ops = NULL;
-
-static int last_run_status;
-
-/* 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
- starts. */
-static struct serial *ocd_desc = NULL;
-
-void
-ocd_error (char *s, int error_code)
-{
- char buf[100];
-
- fputs_filtered (s, gdb_stderr);
- fputs_filtered (" ", gdb_stderr);
-
- switch (error_code)
- {
- case 0x1:
- s = "Unknown fault";
- break;
- case 0x2:
- s = "Power failed";
- break;
- case 0x3:
- s = "Cable disconnected";
- break;
- case 0x4:
- s = "Couldn't enter OCD mode";
- break;
- case 0x5:
- s = "Target stuck in reset";
- 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 0x80:
- s = "Flash erase error";
- break;
- default:
- sprintf (buf, "Unknown error code %d", error_code);
- s = buf;
- }
-
- error (("%s"), s);
-}
-
-/* Return nonzero if the thread TH is still alive on the remote system. */
-
-int
-ocd_thread_alive (ptid_t th)
-{
- return 1;
-}
-
-/* Clean up connection to a remote debugger. */
-
-void
-ocd_close (int quitting)
-{
- if (ocd_desc)
- serial_close (ocd_desc);
- ocd_desc = NULL;
-}
-
-/* Stub for catch_errors. */
-
-static int
-ocd_start_remote (void *dummy)
-{
- unsigned char buf[10], *p;
- int pktlen;
- int status;
- int error_code;
- int speed;
- enum ocd_target_type target_type;
-
- target_type = *(enum ocd_target_type *) dummy;
-
- immediate_quit++; /* Allow user to interrupt it */
-
- serial_send_break (ocd_desc); /* Wake up the wiggler */
-
- speed = 80; /* Divide clock by 4000 */
-
- buf[0] = OCD_INIT;
- buf[1] = speed >> 8;
- buf[2] = speed & 0xff;
- buf[3] = target_type;
- ocd_put_packet (buf, 4); /* Init OCD params */
- p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
-
- if (pktlen < 2)
- error (_("Truncated response packet from OCD device"));
-
- status = p[1];
- error_code = p[2];
-
- if (error_code != 0)
- ocd_error (_("OCD_INIT:"), error_code);
-
- 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 processor is still running, stop it. */
-
- if (!(status & OCD_FLAG_BDM))
- ocd_stop ();
-
- /* 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;
- ocd_put_packet (buf, 3);
-
- p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
-
- if (pktlen < 2)
- error (_("Truncated response packet from OCD device"));
-
- status = p[1];
- error_code = p[2];
-
- if (error_code != 0)
- ocd_error ("OCD_SET_CTL_FLAGS:", error_code);
-
- immediate_quit--;
-
-/* This is really the job of start_remote however, that makes an assumption
- that the target is about to print out a status message of some sort. That
- doesn't happen here (in fact, it may not be possible to get the monitor to
- send the appropriate packet). */
-
- reinit_frame_cache ();
- registers_changed ();
- stop_pc = read_pc ();
- print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC);
-
- 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;
-}
-
-/* Open a connection to a remote debugger.
- NAME is the filename used for communication. */
-
-void
-ocd_open (char *name, int from_tty, enum ocd_target_type target_type,
- struct target_ops *ops)
-{
- unsigned char buf[10], *p;
- 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)."));
-
- target_preopen (from_tty);
-
- current_ops = ops;
-
- unpush_target (current_ops);
-
- ocd_desc = serial_open (name);
- if (!ocd_desc)
- perror_with_name (name);
-
- if (baud_rate != -1)
- {
- if (serial_setbaudrate (ocd_desc, baud_rate))
- {
- serial_close (ocd_desc);
- perror_with_name (name);
- }
- }
-
- serial_raw (ocd_desc);
-
- /* If there is something sitting in the buffer we might take it as a
- response to a command, which would be bad. */
- serial_flush_input (ocd_desc);
-
- if (from_tty)
- {
- puts_filtered ("Remote target wiggler connected to ");
- puts_filtered (name);
- puts_filtered ("\n");
- }
- push_target (current_ops); /* Switch to using remote target now */
-
- /* Without this, some commands which require an active target (such as kill)
- won't work. This variable serves (at least) double duty as both the pid
- of the target process (if it has such), and as a flag indicating that a
- target is active. These functions should be split out into seperate
- variables, especially since GDB will someday have a notion of debugging
- several processes. */
-
- inferior_ptid = pid_to_ptid (42000);
- /* Start the remote connection; if error (0), discard this target.
- 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, &target_type,
- "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
- this is done, GDB can be used to debug some other program. We
- better not have left any breakpoints in the target program or it'll
- die when it hits one. */
-
-void
-ocd_detach (char *args, int from_tty)
-{
- if (args)
- error (_("Argument given to \"detach\" when remotely debugging."));
-
- pop_target ();
- if (from_tty)
- puts_filtered ("Ending remote debugging.\n");
-}
-
-/* Tell the remote machine to resume. */
-
-void
-ocd_resume (ptid_t ptid, int step, enum target_signal siggnal)
-{
- int pktlen;
-
- if (step)
- ocd_do_command (OCD_STEP, &last_run_status, &pktlen);
- else
- ocd_do_command (OCD_RUN, &last_run_status, &pktlen);
-}
-
-void
-ocd_stop (void)
-{
- int status;
- int pktlen;
-
- ocd_do_command (OCD_STOP, &status, &pktlen);
-
- if (!(status & OCD_FLAG_BDM))
- error (_("Can't stop target via BDM"));
-}
-
-static volatile int ocd_interrupt_flag;
-
-/* Send ^C to target to halt it. Target will respond, and send us a
- packet. */
-
-static void
-ocd_interrupt (int signo)
-{
- /* If this doesn't work, try more severe steps. */
- signal (signo, ocd_interrupt_twice);
-
- if (remote_debug)
- printf_unfiltered ("ocd_interrupt called\n");
-
- {
- char buf[1];
-
- ocd_stop ();
- buf[0] = OCD_AYT;
- ocd_put_packet (buf, 1);
- ocd_interrupt_flag = 1;
- }
-}
-
-static void (*ofunc) ();
-
-/* The user typed ^C twice. */
-static void
-ocd_interrupt_twice (int signo)
-{
- signal (signo, ofunc);
-
- interrupt_query ();
-
- signal (signo, ocd_interrupt);
-}
-
-/* Ask the user what to do when an interrupt is received. */
-
-static void
-interrupt_query (void)
-{
- target_terminal_ours ();
-
- if (query ("Interrupted while waiting for the program.\n\
-Give up (and stop debugging it)? "))
- {
- target_mourn_inferior ();
- deprecated_throw_reason (RETURN_QUIT);
- }
-
- target_terminal_inferior ();
-}
-
-/* If nonzero, ignore the next kill. */
-static int kill_kludge;
-
-/* Wait until the remote machine stops, then return,
- storing status in STATUS just as `wait' would.
- Returns "pid" (though it's not clear what, if anything, that
- means in the case of this target). */
-
-int
-ocd_wait (void)
-{
- unsigned char *p;
- int error_code;
- int pktlen;
- char buf[1];
-
- ocd_interrupt_flag = 0;
-
- /* 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 */
-
- while (!(last_run_status & OCD_FLAG_BDM))
- {
- 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"));
-
- last_run_status = p[1];
- error_code = p[2];
-
- if (error_code != 0)
- ocd_error ("target_wait:", error_code);
-
- if (last_run_status & OCD_FLAG_PWF)
- error (_("OCD device lost VCC at BDM interface."));
- else if (last_run_status & OCD_FLAG_CABLE_DISC)
- error (_("OCD device cable appears to have been disconnected."));
- }
-
- if (ocd_interrupt_flag)
- return 1;
- else
- return 0;
-}
-
-/* Read registers from the OCD device. Specify the starting and ending
- register number. Return the number of regs actually read in *NUMREGS.
- Returns a pointer to a static array containing the register contents. */
-
-unsigned char *
-ocd_read_bdm_registers (int first_bdm_regno, int last_bdm_regno, int *reglen)
-{
- unsigned char buf[10];
- int i;
- unsigned char *p;
- unsigned char *regs;
- int error_code, status;
- int pktlen;
-
- buf[0] = OCD_READ_REGS;
- buf[1] = first_bdm_regno >> 8;
- buf[2] = first_bdm_regno & 0xff;
- buf[3] = last_bdm_regno >> 8;
- buf[4] = last_bdm_regno & 0xff;
-
- ocd_put_packet (buf, 5);
- p = ocd_get_packet (OCD_READ_REGS, &pktlen, remote_timeout);
-
- status = p[1];
- error_code = p[2];
-
- if (error_code != 0)
- ocd_error ("read_bdm_registers:", error_code);
-
- i = p[3];
- if (i == 0)
- i = 256;
-
- if (i > pktlen - 4
- || ((i & 3) != 0))
- error (_("Register block size bad: %d"), i);
-
- *reglen = i;
-
- regs = p + 4;
-
- return regs;
-}
-
-/* Read register BDM_REGNO and returns its value ala read_register() */
-
-CORE_ADDR
-ocd_read_bdm_register (int bdm_regno)
-{
- int reglen;
- unsigned char *p;
- CORE_ADDR regval;
-
- p = ocd_read_bdm_registers (bdm_regno, bdm_regno, &reglen);
- regval = extract_unsigned_integer (p, reglen);
-
- return regval;
-}
-
-void
-ocd_write_bdm_registers (int first_bdm_regno, unsigned char *regptr, int reglen)
-{
- unsigned char *buf;
- unsigned char *p;
- int error_code, status;
- int pktlen;
-
- buf = alloca (4 + reglen);
-
- buf[0] = OCD_WRITE_REGS;
- buf[1] = first_bdm_regno >> 8;
- buf[2] = first_bdm_regno & 0xff;
- buf[3] = reglen;
- memcpy (buf + 4, regptr, reglen);
-
- ocd_put_packet (buf, 4 + reglen);
- p = ocd_get_packet (OCD_WRITE_REGS, &pktlen, remote_timeout);
-
- if (pktlen < 3)
- error (_("Truncated response packet from OCD device"));
-
- status = p[1];
- error_code = p[2];
-
- if (error_code != 0)
- ocd_error ("ocd_write_bdm_registers:", error_code);
-}
-
-void
-ocd_write_bdm_register (int bdm_regno, CORE_ADDR reg)
-{
- unsigned char buf[4];
-
- store_unsigned_integer (buf, 4, reg);
-
- ocd_write_bdm_registers (bdm_regno, buf, 4);
-}
-
-void
-ocd_prepare_to_store (void)
-{
-}
-
-/* Write memory data directly to the remote machine.
- This does not inform the data cache; the data cache uses this.
- MEMADDR is the address in the remote memory space.
- MYADDR is the address of the buffer in our space.
- LEN is the number of bytes.
-
- Returns number of bytes transferred, or 0 for error. */
-
-static int write_mem_command = OCD_WRITE_MEM;
-
-int
-ocd_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
-{
- char buf[256 + 10];
- unsigned char *p;
- int origlen;
-
- origlen = len;
-
- buf[0] = write_mem_command;
- buf[5] = 1; /* Write as bytes */
- buf[6] = 0; /* Don't verify */
-
- while (len > 0)
- {
- int numbytes;
- int pktlen;
- int status, error_code;
-
- numbytes = min (len, 256 - 8);
-
- buf[1] = memaddr >> 24;
- buf[2] = memaddr >> 16;
- buf[3] = memaddr >> 8;
- buf[4] = memaddr;
-
- buf[7] = numbytes;
-
- memcpy (&buf[8], myaddr, numbytes);
- ocd_put_packet (buf, 8 + numbytes);
- p = ocd_get_packet (OCD_WRITE_MEM, &pktlen, remote_timeout);
- if (pktlen < 3)
- error (_("Truncated response packet from OCD device"));
-
- status = p[1];
- error_code = p[2];
-
- if (error_code == 0x11) /* Got a bus error? */
- {
- CORE_ADDR error_address;
-
- error_address = p[3] << 24;
- error_address |= p[4] << 16;
- error_address |= p[5] << 8;
- error_address |= p[6];
- numbytes = error_address - memaddr;
-
- len -= numbytes;
-
- errno = EIO;
-
- break;
- }
- else if (error_code != 0)
- ocd_error ("ocd_write_bytes:", error_code);
-
- len -= numbytes;
- memaddr += numbytes;
- myaddr += numbytes;
- }
-
- return origlen - len;
-}
-
-/* Read memory data directly from the remote machine.
- This does not use the data cache; the data cache uses this.
- MEMADDR is the address in the remote memory space.
- MYADDR is the address of the buffer in our space.
- LEN is the number of bytes.
-
- Returns number of bytes transferred, or 0 for error. */
-
-static int
-ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
-{
- char buf[256 + 10];
- unsigned char *p;
- int origlen;
-
- origlen = len;
-
- buf[0] = OCD_READ_MEM;
- buf[5] = 1; /* Read as bytes */
-
- while (len > 0)
- {
- int numbytes;
- int pktlen;
- int status, error_code;
-
- numbytes = min (len, 256 - 7);
-
- buf[1] = memaddr >> 24;
- buf[2] = memaddr >> 16;
- buf[3] = memaddr >> 8;
- buf[4] = memaddr;
-
- buf[6] = numbytes;
-
- ocd_put_packet (buf, 7);
- p = ocd_get_packet (OCD_READ_MEM, &pktlen, remote_timeout);
- if (pktlen < 4)
- error (_("Truncated response packet from OCD device"));
-
- status = p[1];
- error_code = p[2];
-
- if (error_code == 0x11) /* Got a bus error? */
- {
- CORE_ADDR error_address;
-
- error_address = p[3] << 24;
- error_address |= p[4] << 16;
- error_address |= p[5] << 8;
- error_address |= p[6];
- numbytes = error_address - memaddr;
-
- len -= numbytes;
-
- errno = EIO;
-
- break;
- }
- else if (error_code != 0)
- ocd_error ("ocd_read_bytes:", error_code);
-
- memcpy (myaddr, &p[4], numbytes);
-
- len -= numbytes;
- memaddr += numbytes;
- myaddr += numbytes;
- }
-
- return origlen - len;
-}
-
-/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
- to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
- nonzero. Returns length of data written or read; 0 for error. TARGET
- is ignored. */
-
-int
-ocd_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
- struct mem_attrib *attrib, struct target_ops *target)
-{
- int res;
-
- if (should_write)
- res = ocd_write_bytes (memaddr, myaddr, len);
- else
- res = ocd_read_bytes (memaddr, myaddr, len);
-
- return res;
-}
-
-void
-ocd_files_info (struct target_ops *ignore)
-{
- puts_filtered ("Debugging a target over a serial line.\n");
-}
-
-/* Stuff for dealing with the packets which are part of this protocol.
- See comment at top of file for details. */
-
-/* Read a single character from the remote side, handling wierd errors. */
-
-static int
-readchar (int timeout)
-{
- int ch;
-
- ch = serial_readchar (ocd_desc, timeout);
-
- switch (ch)
- {
- case SERIAL_EOF:
- error (_("Remote connection closed"));
- case SERIAL_ERROR:
- perror_with_name (_("Remote communication error"));
- case SERIAL_TIMEOUT:
- default:
- return ch;
- }
-}
-
-/* Send a packet to the OCD device. The packet framed by a SYN character,
- a byte count and a checksum. The byte count only counts the number of
- bytes between the count and the checksum. A count of zero actually
- means 256. Any SYNs within the packet (including the checksum and
- count) must be quoted. The quote character must be quoted as well.
- Quoting is done by replacing the character with the two-character sequence
- DLE, {char} | 0100. Note that the quoting mechanism has no effect on the
- byte count. */
-
-static void
-ocd_put_packet (unsigned char *buf, int len)
-{
- unsigned char checksum;
- unsigned char c;
- unsigned char *packet, *packet_ptr;
-
- packet = alloca (len + 1 + 1); /* packet + SYN + checksum */
- packet_ptr = packet;
-
- checksum = 0;
-
- *packet_ptr++ = 0x55;
-
- while (len-- > 0)
- {
- c = *buf++;
-
- checksum += c;
- *packet_ptr++ = c;
- }
-
- *packet_ptr++ = -checksum;
- if (serial_write (ocd_desc, packet, packet_ptr - packet))
- perror_with_name (_("output_packet: write failed"));
-}
-
-/* Get a packet from the OCD device. Timeout is only enforced for the
- first byte of the packet. Subsequent bytes are expected to arrive in
- time <= remote_timeout. Returns a pointer to a static buffer containing
- the payload of the packet. *LENP contains the length of the packet.
- */
-
-static unsigned char *
-ocd_get_packet (int cmd, int *lenp, int timeout)
-{
- int ch;
- int len;
- static unsigned char packet[512];
- unsigned char *packet_ptr;
- unsigned char checksum;
-
- ch = readchar (timeout);
-
- if (ch < 0)
- error (_("ocd_get_packet (readchar): %d"), ch);
-
- if (ch != 0x55)
- error (_("ocd_get_packet (readchar): %d"), ch);
-
-/* Found the start of a packet */
-
- packet_ptr = packet;
- checksum = 0;
-
-/* Read command char. That sort of tells us how long the packet is. */
-
- ch = readchar (timeout);
-
- if (ch < 0)
- error (_("ocd_get_packet (readchar): %d"), ch);
-
- *packet_ptr++ = ch;
- checksum += ch;
-
-/* Get status. */
-
- ch = readchar (timeout);
-
- if (ch < 0)
- error (_("ocd_get_packet (readchar): %d"), ch);
- *packet_ptr++ = ch;
- checksum += ch;
-
-/* Get error code. */
-
- ch = readchar (timeout);
-
- if (ch < 0)
- error (_("ocd_get_packet (readchar): %d"), ch);
- *packet_ptr++ = ch;
- checksum += ch;
-
- switch (ch) /* Figure out length of packet */
- {
- case 0x7: /* Write verify error? */
- len = 8; /* write address, value read back */
- break;
- case 0x11: /* Bus error? */
- /* write address, read flag */
- case 0x15: /* Internal error */
- len = 5; /* error code, vector */
- break;
- default: /* Error w/no params */
- len = 0;
- break;
- case 0x0: /* Normal result */
- switch (packet[0])
- {
- case OCD_AYT: /* Are You There? */
- case OCD_SET_BAUD_RATE: /* Set Baud Rate */
- case OCD_INIT: /* Initialize OCD device */
- case OCD_SET_SPEED: /* Set Speed */
- case OCD_SET_FUNC_CODE: /* Set Function Code */
- case OCD_SET_CTL_FLAGS: /* Set Control Flags */
- case OCD_SET_BUF_ADDR: /* Set Register Buffer Address */
- case OCD_RUN: /* Run Target from PC */
- case OCD_RUN_ADDR: /* Run Target from Specified Address */
- case OCD_STOP: /* Stop Target */
- case OCD_RESET_RUN: /* Reset Target and Run */
- case OCD_RESET: /* Reset Target and Halt */
- case OCD_STEP: /* Single Step */
- case OCD_WRITE_REGS: /* Write Register */
- case OCD_WRITE_MEM: /* Write Memory */
- case OCD_FILL_MEM: /* Fill Memory */
- case OCD_MOVE_MEM: /* Move Memory */
- case OCD_WRITE_INT_MEM: /* Write Internal Memory */
- case OCD_JUMP: /* Jump to Subroutine */
- case OCD_ERASE_FLASH: /* Erase flash memory */
- 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 = 10;
- break;
- case OCD_GET_STATUS_MASK: /* Get Status Mask */
- len = 1;
- break;
- case OCD_GET_CTRS: /* Get Error Counters */
- case OCD_READ_REGS: /* Read Register */
- case OCD_READ_MEM: /* Read Memory */
- case OCD_READ_INT_MEM: /* Read Internal Memory */
- len = 257;
- break;
- default:
- error (_("ocd_get_packet: unknown packet type 0x%x."), ch);
- }
- }
-
- if (len == 257) /* Byte stream? */
- { /* Yes, byte streams contain the length */
- ch = readchar (timeout);
-
- if (ch < 0)
- error (_("ocd_get_packet (readchar): %d"), ch);
- *packet_ptr++ = ch;
- checksum += ch;
- len = ch;
- if (len == 0)
- len = 256;
- }
-
- while (len-- >= 0) /* Do rest of packet and checksum */
- {
- ch = readchar (timeout);
-
- if (ch < 0)
- error (_("ocd_get_packet (readchar): %d"), ch);
- *packet_ptr++ = ch;
- checksum += ch;
- }
-
- if (checksum != 0)
- 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);
-
- *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */
- return packet;
-}
-
-/* Execute a simple (one-byte) command. Returns a pointer to the data
- following the error code. */
-
-static unsigned char *
-ocd_do_command (int cmd, int *statusp, int *lenp)
-{
- unsigned char buf[100], *p;
- 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 (*lenp < 3)
- error (_("Truncated response packet from OCD device"));
-
- status = p[1];
- error_code = p[2];
-
- if (error_code != 0)
- {
- sprintf (errbuf, "ocd_do_command (0x%x):", cmd);
- ocd_error (errbuf, error_code);
- }
-
- if (status & OCD_FLAG_PWF)
- error (_("OCD device can't detect VCC at BDM interface."));
- else if (status & OCD_FLAG_CABLE_DISC)
- error (_("BDM cable appears to be disconnected."));
-
- *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;
-}
-
-void
-ocd_kill (void)
-{
- /* For some mysterious reason, wait_for_inferior calls kill instead of
- mourn after it gets TARGET_WAITKIND_SIGNALLED. Work around it. */
- if (kill_kludge)
- {
- kill_kludge = 0;
- target_mourn_inferior ();
- return;
- }
-
- /* Don't wait for it to die. I'm not really sure it matters whether
- we do or not. */
- target_mourn_inferior ();
-}
-
-void
-ocd_mourn (void)
-{
- unpush_target (current_ops);
- generic_mourn_inferior ();
-}
-
-/* All we actually do is set the PC to the start address of exec_bfd. */
-
-void
-ocd_create_inferior (char *exec_file, char *args, char **env, int from_tty)
-{
- if (args && (*args != '\000'))
- error (_("Args are not supported by BDM."));
-
- clear_proceed_status ();
- write_pc (bfd_get_start_address (exec_bfd));
-}
-
-void
-ocd_load (char *args, int from_tty)
-{
- generic_load (args, from_tty);
-
- inferior_ptid = null_ptid;
-
-/* This is necessary because many things were based on the PC at the time that
- we attached to the monitor, which is no longer valid now that we have loaded
- new code (and just changed the PC). Another way to do this might be to call
- normal_stop, except that the stack may not be valid, and things would get
- horribly confused... */
-
- 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 */
-
-/* BDM (at least on CPU32) uses a different breakpoint */
-
-int
-ocd_insert_breakpoint (struct bp_target_info *bp_tgt)
-{
- static char break_insn[] = BDM_BREAKPOINT;
- int val;
-
- bp_tgt->placed_size = bp_tgt->shadow_len = sizeof (break_insn);
- val = target_read_memory (bp_tgt->placed_address, bp_tgt->shadow_contents,
- bp_tgt->placed_size);
-
- if (val == 0)
- val = target_write_memory (bp_tgt->placed_address, break_insn,
- bp_tgt->placed_size);
-
- return val;
-}
-
-int
-ocd_remove_breakpoint (struct bp_target_info *bp_tgt)
-{
- return target_write_memory (bp_tgt->placed_address, bp_tgt->shadow_contents,
- bp_tgt->placed_size);
-}
-
-static void
-bdm_command (char *args, int from_tty)
-{
- error (_("bdm command must be followed by `reset'"));
-}
-
-static void
-bdm_reset_command (char *args, int from_tty)
-{
- int status, pktlen;
-
- if (!ocd_desc)
- error (_("Not connected to OCD device."));
-
- ocd_do_command (OCD_RESET, &status, &pktlen);
- dcache_invalidate (target_dcache);
- registers_changed ();
-}
-
-static void
-bdm_restart_command (char *args, int from_tty)
-{
- int status, pktlen;
-
- if (!ocd_desc)
- error (_("Not connected to OCD device."));
-
- ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
- last_run_status = status;
- clear_proceed_status ();
- wait_for_inferior ();
- normal_stop ();
-}
-
-/* Temporary replacement for target_store_registers(). This prevents
- generic_load from trying to set the PC. */
-
-static void
-noop_store_registers (int regno)
-{
-}
-
-static void
-bdm_update_flash_command (char *args, int from_tty)
-{
- int status, pktlen;
- struct cleanup *old_chain;
- void (*store_registers_tmp) (int);
-
- if (!ocd_desc)
- error (_("Not connected to OCD device."));
-
- if (!args)
- error (_("Must specify file containing new OCD code."));
-
-/* old_chain = make_cleanup (flash_cleanup, 0); */
-
- ocd_do_command (OCD_ENTER_MON, &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 = noop_store_registers;
-
- generic_load (args, from_tty);
-
- current_target.to_store_registers = store_registers_tmp;
- write_mem_command = OCD_WRITE_MEM;
-
- ocd_do_command (OCD_EXIT_MON, &status, &pktlen);
-
-/* discard_cleanups (old_chain); */
-}
-
-extern initialize_file_ftype _initialize_remote_ocd; /* -Wmissing-prototypes */
-
-void
-_initialize_remote_ocd (void)
-{
- extern struct cmd_list_element *cmdlist;
- static struct cmd_list_element *ocd_cmd_list = NULL;
-
- add_setshow_integer_cmd ("remotetimeout", no_class, &remote_timeout, _("\
-Set timeout value for remote read."), _("\
-Show timeout value for remote read."), NULL,
- NULL,
- NULL, /* FIXME: i18n: */
- &setlist, &showlist);
-
- /* FIXME: i18n: What documentation? */
- add_prefix_cmd ("ocd", class_obscure, bdm_command, (""), &ocd_cmd_list,
- "ocd ", 0, &cmdlist);
-
- /* FIXME: i18n: what documentation? */
- add_cmd ("reset", class_obscure, bdm_reset_command, (""), &ocd_cmd_list);
- add_cmd ("restart", class_obscure, bdm_restart_command, (""), &ocd_cmd_list);
- add_cmd ("update-flash", class_obscure, bdm_update_flash_command, (""), &ocd_cmd_list);
-}