/* Target communications support for Macraigor Systems' On-Chip Debugging

   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2006
   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).  */

  flush_cached_frames ();
  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);
}
