/* Remote debugging interface for M32R/SDI.

   Copyright (C) 2003-2012 Free Software Foundation, Inc.

   Contributed by Renesas Technology Co.
   Written by Kei Sakamoto <sakamoto.kei@renesas.com>.

   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 3 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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "inferior.h"
#include "target.h"
#include "regcache.h"
#include "gdb_string.h"
#include "gdbthread.h"
#include <ctype.h>
#include <signal.h>
#ifdef __MINGW32__
#include <winsock2.h>
#else
#include <netinet/in.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <signal.h>
#include <time.h>


#include "serial.h"

/* Descriptor for I/O to remote machine.  */

static struct serial *sdi_desc = NULL;

#define SDI_TIMEOUT 30


#define SDIPORT 3232

static char chip_name[64];

static int step_mode;
static unsigned long last_pc_addr = 0xffffffff;
static unsigned char last_pc_addr_data[2];

static int mmu_on = 0;

static int use_ib_breakpoints = 1;

#define MAX_BREAKPOINTS 1024
static int max_ib_breakpoints;
static unsigned long bp_address[MAX_BREAKPOINTS];
static unsigned char bp_data[MAX_BREAKPOINTS][4];

/* dbt -> nop */
static const unsigned char dbt_bp_entry[] = {
  0x10, 0xe0, 0x70, 0x00
};

#define MAX_ACCESS_BREAKS 4
static int max_access_breaks;
static unsigned long ab_address[MAX_ACCESS_BREAKS];
static unsigned int ab_type[MAX_ACCESS_BREAKS];
static unsigned int ab_size[MAX_ACCESS_BREAKS];
static CORE_ADDR hit_watchpoint_addr = 0;

static int interrupted = 0;

/* Forward data declarations */
extern struct target_ops m32r_ops;

/* This is the ptid we use while we're connected to the remote.  Its
   value is arbitrary, as the target doesn't have a notion of
   processes or threads, but we need something non-null to place in
   inferior_ptid.  */
static ptid_t remote_m32r_ptid;

/* Commands */
#define SDI_OPEN                 1
#define SDI_CLOSE                2
#define SDI_RELEASE              3
#define SDI_READ_CPU_REG         4
#define SDI_WRITE_CPU_REG        5
#define SDI_READ_MEMORY          6
#define SDI_WRITE_MEMORY         7
#define SDI_EXEC_CPU             8
#define SDI_STOP_CPU             9
#define SDI_WAIT_FOR_READY      10
#define SDI_GET_ATTR            11
#define SDI_SET_ATTR            12
#define SDI_STATUS              13

/* Attributes */
#define SDI_ATTR_NAME            1
#define SDI_ATTR_BRK             2
#define SDI_ATTR_ABRK            3
#define SDI_ATTR_CACHE           4
#define SDI_CACHE_TYPE_M32102    0
#define SDI_CACHE_TYPE_CHAOS     1
#define SDI_ATTR_MEM_ACCESS      5
#define SDI_MEM_ACCESS_DEBUG_DMA 0
#define SDI_MEM_ACCESS_MON_CODE  1

/* Registers */
#define SDI_REG_R0               0
#define SDI_REG_R1               1
#define SDI_REG_R2               2
#define SDI_REG_R3               3
#define SDI_REG_R4               4
#define SDI_REG_R5               5
#define SDI_REG_R6               6
#define SDI_REG_R7               7
#define SDI_REG_R8               8
#define SDI_REG_R9               9
#define SDI_REG_R10             10
#define SDI_REG_R11             11
#define SDI_REG_R12             12
#define SDI_REG_FP              13
#define SDI_REG_LR              14
#define SDI_REG_SP              15
#define SDI_REG_PSW             16
#define SDI_REG_CBR             17
#define SDI_REG_SPI             18
#define SDI_REG_SPU             19
#define SDI_REG_CR4             20
#define SDI_REG_EVB             21
#define SDI_REG_BPC             22
#define SDI_REG_CR7             23
#define SDI_REG_BBPSW           24
#define SDI_REG_CR9             25
#define SDI_REG_CR10            26
#define SDI_REG_CR11            27
#define SDI_REG_CR12            28
#define SDI_REG_WR              29
#define SDI_REG_BBPC            30
#define SDI_REG_PBP             31
#define SDI_REG_ACCH            32
#define SDI_REG_ACCL            33
#define SDI_REG_ACC1H           34
#define SDI_REG_ACC1L           35


/* Low level communication functions.  */

/* Check an ack packet from the target.  */
static int
get_ack (void)
{
  int c;

  if (!sdi_desc)
    return -1;

  c = serial_readchar (sdi_desc, SDI_TIMEOUT);

  if (c < 0)
    return -1;

  if (c != '+')			/* error */
    return -1;

  return 0;
}

/* Send data to the target and check an ack packet.  */
static int
send_data (void *buf, int len)
{
  if (!sdi_desc)
    return -1;

  if (serial_write (sdi_desc, buf, len) != 0)
    return -1;

  if (get_ack () == -1)
    return -1;

  return len;
}

/* Receive data from the target.  */
static int
recv_data (void *buf, int len)
{
  int total = 0;
  int c;

  if (!sdi_desc)
    return -1;

  while (total < len)
    {
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);

      if (c < 0)
	return -1;

      ((unsigned char *) buf)[total++] = c;
    }

  return len;
}

/* Store unsigned long parameter on packet.  */
static void
store_long_parameter (void *buf, long val)
{
  val = htonl (val);
  memcpy (buf, &val, 4);
}

static int
send_cmd (unsigned char cmd)
{
  unsigned char buf[1];

  buf[0] = cmd;
  return send_data (buf, 1);
}

static int
send_one_arg_cmd (unsigned char cmd, unsigned char arg1)
{
  unsigned char buf[2];

  buf[0] = cmd;
  buf[1] = arg1;
  return send_data (buf, 2);
}

static int
send_two_arg_cmd (unsigned char cmd, unsigned char arg1, unsigned long arg2)
{
  unsigned char buf[6];

  buf[0] = cmd;
  buf[1] = arg1;
  store_long_parameter (buf + 2, arg2);
  return send_data (buf, 6);
}

static int
send_three_arg_cmd (unsigned char cmd, unsigned long arg1, unsigned long arg2,
		    unsigned long arg3)
{
  unsigned char buf[13];

  buf[0] = cmd;
  store_long_parameter (buf + 1, arg1);
  store_long_parameter (buf + 5, arg2);
  store_long_parameter (buf + 9, arg3);
  return send_data (buf, 13);
}

static unsigned char
recv_char_data (void)
{
  unsigned char val;

  recv_data (&val, 1);
  return val;
}

static unsigned long
recv_long_data (void)
{
  unsigned long val;

  recv_data (&val, 4);
  return ntohl (val);
}


/* Check if MMU is on.  */
static void
check_mmu_status (void)
{
  unsigned long val;

  /* Read PC address.  */
  if (send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BPC) == -1)
    return;
  val = recv_long_data ();
  if ((val & 0xc0000000) == 0x80000000)
    {
      mmu_on = 1;
      return;
    }

  /* Read EVB address.  */
  if (send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_EVB) == -1)
    return;
  val = recv_long_data ();
  if ((val & 0xc0000000) == 0x80000000)
    {
      mmu_on = 1;
      return;
    }

  mmu_on = 0;
}


/* This is called not only when we first attach, but also when the
   user types "run" after having attached.  */
static void
m32r_create_inferior (struct target_ops *ops, char *execfile,
		      char *args, char **env, int from_tty)
{
  CORE_ADDR entry_pt;

  if (args && *args)
    error (_("Cannot pass arguments to remote STDEBUG process"));

  if (execfile == 0 || exec_bfd == 0)
    error (_("No executable file specified"));

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_create_inferior(%s,%s)\n", execfile,
			args);

  entry_pt = bfd_get_start_address (exec_bfd);

  /* The "process" (board) is already stopped awaiting our commands, and
     the program is already downloaded.  We just set its PC and go.  */

  clear_proceed_status ();

  /* Tell wait_for_inferior that we've started a new process.  */
  init_wait_for_inferior ();

  /* Set up the "saved terminal modes" of the inferior
     based on what modes we are starting it with.  */
  target_terminal_init ();

  /* Install inferior's terminal modes.  */
  target_terminal_inferior ();

  regcache_write_pc (get_current_regcache (), entry_pt);
}

/* Open a connection to a remote debugger.
   NAME is the filename used for communication.  */

static void
m32r_open (char *args, int from_tty)
{
  struct hostent *host_ent;
  struct sockaddr_in server_addr;
  char *port_str, hostname[256];
  int port;
  int i, n;
  int yes = 1;

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_open(%d)\n", from_tty);

  target_preopen (from_tty);

  push_target (&m32r_ops);

  if (args == NULL)
    sprintf (hostname, "localhost:%d", SDIPORT);
  else
    {
      port_str = strchr (args, ':');
      if (port_str == NULL)
	sprintf (hostname, "%s:%d", args, SDIPORT);
      else
	strcpy (hostname, args);
    }

  sdi_desc = serial_open (hostname);
  if (!sdi_desc)
    error (_("Connection refused."));

  if (get_ack () == -1)
    error (_("Cannot connect to SDI target."));

  if (send_cmd (SDI_OPEN) == -1)
    error (_("Cannot connect to SDI target."));

  /* Get maximum number of ib breakpoints.  */
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_BRK);
  max_ib_breakpoints = recv_char_data ();
  if (remote_debug)
    printf_filtered ("Max IB Breakpoints = %d\n", max_ib_breakpoints);

  /* Initialize breakpoints.  */
  for (i = 0; i < MAX_BREAKPOINTS; i++)
    bp_address[i] = 0xffffffff;

  /* Get maximum number of access breaks.  */
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_ABRK);
  max_access_breaks = recv_char_data ();
  if (remote_debug)
    printf_filtered ("Max Access Breaks = %d\n", max_access_breaks);

  /* Initialize access breask.  */
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
    ab_address[i] = 0x00000000;

  check_mmu_status ();

  /* Get the name of chip on target board.  */
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_NAME);
  recv_data (chip_name, 64);

  if (from_tty)
    printf_filtered ("Remote %s connected to %s\n", target_shortname,
		     chip_name);
}

/* Close out all files and local state before this target loses control.  */

static void
m32r_close (int quitting)
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_close(%d)\n", quitting);

  if (sdi_desc)
    {
      send_cmd (SDI_CLOSE);
      serial_close (sdi_desc);
      sdi_desc = NULL;
    }

  inferior_ptid = null_ptid;
  delete_thread_silent (remote_m32r_ptid);
  return;
}

/* Tell the remote machine to resume.  */

static void
m32r_resume (struct target_ops *ops,
	     ptid_t ptid, int step, enum gdb_signal sig)
{
  unsigned long pc_addr, bp_addr, ab_addr;
  int ib_breakpoints;
  unsigned char buf[13];
  int i;

  if (remote_debug)
    {
      if (step)
	fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(step)\n");
      else
	fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(cont)\n");
    }

  check_mmu_status ();

  pc_addr = regcache_read_pc (get_current_regcache ());
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "pc <= 0x%lx\n", pc_addr);

  /* At pc address there is a parallel instruction with +2 offset,
     so we have to make it a serial instruction or avoid it.  */
  if (pc_addr == last_pc_addr)
    {
      /* Avoid a parallel nop.  */
      if (last_pc_addr_data[0] == 0xf0 && last_pc_addr_data[1] == 0x00)
	{
	  pc_addr += 2;
	  /* Now we can forget this instruction.  */
	  last_pc_addr = 0xffffffff;
	}
      /* Clear a parallel bit.  */
      else
	{
	  buf[0] = SDI_WRITE_MEMORY;
	  if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
	    store_long_parameter (buf + 1, pc_addr);
	  else
	    store_long_parameter (buf + 1, pc_addr - 1);
	  store_long_parameter (buf + 5, 1);
	  buf[9] = last_pc_addr_data[0] & 0x7f;
	  send_data (buf, 10);
	}
    }

  /* Set PC.  */
  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BPC, pc_addr);

  /* step mode.  */
  step_mode = step;
  if (step)
    {
      /* Set PBP.  */
      send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PBP, pc_addr | 1);
    }
  else
    {
      /* Unset PBP.  */
      send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PBP, 0x00000000);
    }

  if (use_ib_breakpoints)
    ib_breakpoints = max_ib_breakpoints;
  else
    ib_breakpoints = 0;

  /* Set ib breakpoints.  */
  for (i = 0; i < ib_breakpoints; i++)
    {
      bp_addr = bp_address[i];

      if (bp_addr == 0xffffffff)
	continue;

      /* Set PBP.  */
      if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
	send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
			    0x00000006);
      else
	send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
			    0x06000000);

      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8080 + 4 * i, 4, bp_addr);
    }

  /* Set dbt breakpoints.  */
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
    {
      bp_addr = bp_address[i];

      if (bp_addr == 0xffffffff)
	continue;

      if (!mmu_on)
	bp_addr &= 0x7fffffff;

      /* Write DBT instruction.  */
      buf[0] = SDI_WRITE_MEMORY;
      store_long_parameter (buf + 1, (bp_addr & 0xfffffffc));
      store_long_parameter (buf + 5, 4);
      if ((bp_addr & 2) == 0 && bp_addr != (pc_addr & 0xfffffffc))
	{
	  if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
	    {
	      buf[9] = dbt_bp_entry[0];
	      buf[10] = dbt_bp_entry[1];
	      buf[11] = dbt_bp_entry[2];
	      buf[12] = dbt_bp_entry[3];
	    }
	  else
	    {
	      buf[9] = dbt_bp_entry[3];
	      buf[10] = dbt_bp_entry[2];
	      buf[11] = dbt_bp_entry[1];
	      buf[12] = dbt_bp_entry[0];
	    }
	}
      else
	{
	  if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
	    {
	      if ((bp_addr & 2) == 0)
		{
		  buf[9] = dbt_bp_entry[0];
		  buf[10] = dbt_bp_entry[1];
		  buf[11] = bp_data[i][2] & 0x7f;
		  buf[12] = bp_data[i][3];
		}
	      else
		{
		  buf[9] = bp_data[i][0];
		  buf[10] = bp_data[i][1];
		  buf[11] = dbt_bp_entry[0];
		  buf[12] = dbt_bp_entry[1];
		}
	    }
	  else
	    {
	      if ((bp_addr & 2) == 0)
		{
		  buf[9] = bp_data[i][0];
		  buf[10] = bp_data[i][1] & 0x7f;
		  buf[11] = dbt_bp_entry[1];
		  buf[12] = dbt_bp_entry[0];
		}
	      else
		{
		  buf[9] = dbt_bp_entry[1];
		  buf[10] = dbt_bp_entry[0];
		  buf[11] = bp_data[i][2];
		  buf[12] = bp_data[i][3];
		}
	    }
	}
      send_data (buf, 13);
    }

  /* Set access breaks.  */
  for (i = 0; i < max_access_breaks; i++)
    {
      ab_addr = ab_address[i];

      if (ab_addr == 0x00000000)
	continue;

      /* DBC register.  */
      if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
	{
	  switch (ab_type[i])
	    {
	    case 0:		/* write watch */
	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
				  0x00000086);
	      break;
	    case 1:		/* read watch */
	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
				  0x00000046);
	      break;
	    case 2:		/* access watch */
	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
				  0x00000006);
	      break;
	    }
	}
      else
	{
	  switch (ab_type[i])
	    {
	    case 0:		/* write watch */
	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
				  0x86000000);
	      break;
	    case 1:		/* read watch */
	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
				  0x46000000);
	      break;
	    case 2:		/* access watch */
	      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
				  0x06000000);
	      break;
	    }
	}

      /* DBAH register.  */
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8180 + 4 * i, 4, ab_addr);

      /* DBAL register.  */
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8200 + 4 * i, 4,
			  0xffffffff);

      /* DBD register.  */
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8280 + 4 * i, 4,
			  0x00000000);

      /* DBDM register.  */
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8300 + 4 * i, 4,
			  0x00000000);
    }

  /* Resume program.  */
  send_cmd (SDI_EXEC_CPU);

  /* 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 = remote_m32r_ptid;
  add_thread_silent (remote_m32r_ptid);

  return;
}

/* Wait until the remote machine stops, then return,
   storing status in STATUS just as `wait' would.  */

static void
gdb_cntrl_c (int signo)
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "interrupt\n");
  interrupted = 1;
}

static ptid_t
m32r_wait (struct target_ops *ops,
	   ptid_t ptid, struct target_waitstatus *status, int options)
{
  static RETSIGTYPE (*prev_sigint) ();
  unsigned long bp_addr, pc_addr;
  int ib_breakpoints;
  long i;
  unsigned char buf[13];
  int ret, c;

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_wait()\n");

  status->kind = TARGET_WAITKIND_EXITED;
  status->value.sig = GDB_SIGNAL_0;

  interrupted = 0;
  prev_sigint = signal (SIGINT, gdb_cntrl_c);

  /* Wait for ready.  */
  buf[0] = SDI_WAIT_FOR_READY;
  if (serial_write (sdi_desc, buf, 1) != 0)
    error (_("Remote connection closed"));

  while (1)
    {
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      if (c < 0)
	error (_("Remote connection closed"));

      if (c == '-')		/* error */
	{
	  status->kind = TARGET_WAITKIND_STOPPED;
	  status->value.sig = GDB_SIGNAL_HUP;
	  return inferior_ptid;
	}
      else if (c == '+')	/* stopped */
	break;

      if (interrupted)
	ret = serial_write (sdi_desc, "!", 1);	/* packet to interrupt */
      else
	ret = serial_write (sdi_desc, ".", 1);	/* packet to wait */
      if (ret != 0)
	error (_("Remote connection closed"));
    }

  status->kind = TARGET_WAITKIND_STOPPED;
  if (interrupted)
    status->value.sig = GDB_SIGNAL_INT;
  else
    status->value.sig = GDB_SIGNAL_TRAP;

  interrupted = 0;
  signal (SIGINT, prev_sigint);

  check_mmu_status ();

  /* Recover parallel bit.  */
  if (last_pc_addr != 0xffffffff)
    {
      buf[0] = SDI_WRITE_MEMORY;
      if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
	store_long_parameter (buf + 1, last_pc_addr);
      else
	store_long_parameter (buf + 1, last_pc_addr - 1);
      store_long_parameter (buf + 5, 1);
      buf[9] = last_pc_addr_data[0];
      send_data (buf, 10);
      last_pc_addr = 0xffffffff;
    }

  if (use_ib_breakpoints)
    ib_breakpoints = max_ib_breakpoints;
  else
    ib_breakpoints = 0;

  /* Set back pc by 2 if m32r is stopped with dbt.  */
  last_pc_addr = 0xffffffff;
  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BPC);
  pc_addr = recv_long_data () - 2;
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
    {
      if (pc_addr == bp_address[i])
	{
	  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BPC, pc_addr);

	  /* If there is a parallel instruction with +2 offset at pc
	     address, we have to take care of it later.  */
	  if ((pc_addr & 0x2) != 0)
	    {
	      if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
		{
		  if ((bp_data[i][2] & 0x80) != 0)
		    {
		      last_pc_addr = pc_addr;
		      last_pc_addr_data[0] = bp_data[i][2];
		      last_pc_addr_data[1] = bp_data[i][3];
		    }
		}
	      else
		{
		  if ((bp_data[i][1] & 0x80) != 0)
		    {
		      last_pc_addr = pc_addr;
		      last_pc_addr_data[0] = bp_data[i][1];
		      last_pc_addr_data[1] = bp_data[i][0];
		    }
		}
	    }
	  break;
	}
    }

  /* Remove ib breakpoints.  */
  for (i = 0; i < ib_breakpoints; i++)
    {
      if (bp_address[i] != 0xffffffff)
	send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
			    0x00000000);
    }
  /* Remove dbt breakpoints.  */
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
    {
      bp_addr = bp_address[i];
      if (bp_addr != 0xffffffff)
	{
	  if (!mmu_on)
	    bp_addr &= 0x7fffffff;
	  buf[0] = SDI_WRITE_MEMORY;
	  store_long_parameter (buf + 1, bp_addr & 0xfffffffc);
	  store_long_parameter (buf + 5, 4);
	  buf[9] = bp_data[i][0];
	  buf[10] = bp_data[i][1];
	  buf[11] = bp_data[i][2];
	  buf[12] = bp_data[i][3];
	  send_data (buf, 13);
	}
    }

  /* Remove access breaks.  */
  hit_watchpoint_addr = 0;
  for (i = 0; i < max_access_breaks; i++)
    {
      if (ab_address[i] != 0x00000000)
	{
	  buf[0] = SDI_READ_MEMORY;
	  store_long_parameter (buf + 1, 0xffff8100 + 4 * i);
	  store_long_parameter (buf + 5, 4);
	  serial_write (sdi_desc, buf, 9);
	  c = serial_readchar (sdi_desc, SDI_TIMEOUT);
	  if (c != '-' && recv_data (buf, 4) != -1)
	    {
	      if (gdbarch_byte_order (target_gdbarch) == BFD_ENDIAN_BIG)
		{
		  if ((buf[3] & 0x1) == 0x1)
		    hit_watchpoint_addr = ab_address[i];
		}
	      else
		{
		  if ((buf[0] & 0x1) == 0x1)
		    hit_watchpoint_addr = ab_address[i];
		}
	    }

	  send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
			      0x00000000);
	}
    }

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "pc => 0x%lx\n", pc_addr);

  return inferior_ptid;
}

/* Terminate the open connection to the remote debugger.
   Use this when you want to detach and do something else
   with your gdb.  */
static void
m32r_detach (struct target_ops *ops, char *args, int from_tty)
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_detach(%d)\n", from_tty);

  m32r_resume (ops, inferior_ptid, 0, GDB_SIGNAL_0);

  /* Calls m32r_close to do the real work.  */
  pop_target ();
  if (from_tty)
    fprintf_unfiltered (gdb_stdlog, "Ending remote %s debugging\n",
			target_shortname);
}

/* Return the id of register number REGNO.  */

static int
get_reg_id (int regno)
{
  switch (regno)
    {
    case 20:
      return SDI_REG_BBPC;
    case 21:
      return SDI_REG_BPC;
    case 22:
      return SDI_REG_ACCL;
    case 23:
      return SDI_REG_ACCH;
    case 24:
      return SDI_REG_EVB;
    }

  return regno;
}

/* Fetch register REGNO, or all registers if REGNO is -1.
   Returns errno value.  */
static void
m32r_fetch_register (struct target_ops *ops,
		     struct regcache *regcache, int regno)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned long val, val2, regid;

  if (regno == -1)
    {
      for (regno = 0;
	   regno < gdbarch_num_regs (get_regcache_arch (regcache));
	   regno++)
	m32r_fetch_register (ops, regcache, regno);
    }
  else
    {
      char buffer[MAX_REGISTER_SIZE];

      regid = get_reg_id (regno);
      send_one_arg_cmd (SDI_READ_CPU_REG, regid);
      val = recv_long_data ();

      if (regid == SDI_REG_PSW)
	{
	  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
	  val2 = recv_long_data ();
	  val = ((0x00cf & val2) << 8) | ((0xcf00 & val) >> 8);
	}

      if (remote_debug)
	fprintf_unfiltered (gdb_stdlog, "m32r_fetch_register(%d,0x%08lx)\n",
			    regno, val);

      /* We got the number the register holds, but gdb expects to see a
         value in the target byte ordering.  */
      store_unsigned_integer (buffer, 4, byte_order, val);
      regcache_raw_supply (regcache, regno, buffer);
    }
  return;
}

/* Store register REGNO, or all if REGNO == 0.
   Return errno value.  */
static void
m32r_store_register (struct target_ops *ops,
		     struct regcache *regcache, int regno)
{
  int regid;
  ULONGEST regval, tmp;

  if (regno == -1)
    {
      for (regno = 0;
	   regno < gdbarch_num_regs (get_regcache_arch (regcache));
	   regno++)
	m32r_store_register (ops, regcache, regno);
    }
  else
    {
      regcache_cooked_read_unsigned (regcache, regno, &regval);
      regid = get_reg_id (regno);

      if (regid == SDI_REG_PSW)
	{
	  unsigned long psw, bbpsw;

	  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_PSW);
	  psw = recv_long_data ();

	  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
	  bbpsw = recv_long_data ();

	  tmp = (0x00cf & psw) | ((0x00cf & regval) << 8);
	  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PSW, tmp);

	  tmp = (0x0030 & bbpsw) | ((0xcf00 & regval) >> 8);
	  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BBPSW, tmp);
	}
      else
	{
	  send_two_arg_cmd (SDI_WRITE_CPU_REG, regid, regval);
	}

      if (remote_debug)
	fprintf_unfiltered (gdb_stdlog, "m32r_store_register(%d,0x%08lu)\n",
			    regno, (unsigned long) regval);
    }
}

/* Get ready to modify the registers array.  On machines which store
   individual registers, this doesn't need to do anything.  On machines
   which store all the registers in one fell swoop, this makes sure
   that registers contains all the registers from the program being
   debugged.  */

static void
m32r_prepare_to_store (struct regcache *regcache)
{
  /* Do nothing, since we can store individual regs.  */
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_prepare_to_store()\n");
}

static void
m32r_files_info (struct target_ops *target)
{
  const char *file = "nothing";

  if (exec_bfd)
    {
      file = bfd_get_filename (exec_bfd);
      printf_filtered ("\tAttached to %s running program %s\n",
		       chip_name, file);
    }
}

/* Read/Write memory.  */
static int
m32r_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
		  int write,
		  struct mem_attrib *attrib, struct target_ops *target)
{
  unsigned long taddr;
  unsigned char buf[0x2000];
  int ret, c;

  taddr = memaddr;

  if (!mmu_on)
    {
      if ((taddr & 0xa0000000) == 0x80000000)
	taddr &= 0x7fffffff;
    }

  if (remote_debug)
    {
      if (write)
	fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%s,%d,write)\n",
			    paddress (target_gdbarch, memaddr), len);
      else
	fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%s,%d,read)\n",
			    paddress (target_gdbarch, memaddr), len);
    }

  if (write)
    {
      buf[0] = SDI_WRITE_MEMORY;
      store_long_parameter (buf + 1, taddr);
      store_long_parameter (buf + 5, len);
      if (len < 0x1000)
	{
	  memcpy (buf + 9, myaddr, len);
	  ret = send_data (buf, len + 9) - 9;
	}
      else
	{
	  if (serial_write (sdi_desc, buf, 9) != 0)
	    {
	      if (remote_debug)
		fprintf_unfiltered (gdb_stdlog,
				    "m32r_xfer_memory() failed\n");
	      return 0;
	    }
	  ret = send_data (myaddr, len);
	}
    }
  else
    {
      buf[0] = SDI_READ_MEMORY;
      store_long_parameter (buf + 1, taddr);
      store_long_parameter (buf + 5, len);
      if (serial_write (sdi_desc, buf, 9) != 0)
	{
	  if (remote_debug)
	    fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n");
	  return 0;
	}

      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      if (c < 0 || c == '-')
	{
	  if (remote_debug)
	    fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n");
	  return 0;
	}

      ret = recv_data (myaddr, len);
    }

  if (ret <= 0)
    {
      if (remote_debug)
	fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() fails\n");
      return 0;
    }

  return ret;
}

static void
m32r_kill (struct target_ops *ops)
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_kill()\n");

  inferior_ptid = null_ptid;
  delete_thread_silent (remote_m32r_ptid);

  return;
}

/* Clean up when a program exits.

   The program actually lives on in the remote processor's RAM, and may be
   run again without a download.  Don't leave it full of breakpoint
   instructions.  */

static void
m32r_mourn_inferior (struct target_ops *ops)
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_mourn_inferior()\n");

  remove_breakpoints ();
  generic_mourn_inferior ();
}

static int
m32r_insert_breakpoint (struct gdbarch *gdbarch,
			struct bp_target_info *bp_tgt)
{
  CORE_ADDR addr = bp_tgt->placed_address;
  int ib_breakpoints;
  unsigned char buf[13];
  int i, c;

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%s,...)\n",
			paddress (gdbarch, addr));

  if (use_ib_breakpoints)
    ib_breakpoints = max_ib_breakpoints;
  else
    ib_breakpoints = 0;

  for (i = 0; i < MAX_BREAKPOINTS; i++)
    {
      if (bp_address[i] == 0xffffffff)
	{
	  bp_address[i] = addr;
	  if (i >= ib_breakpoints)
	    {
	      buf[0] = SDI_READ_MEMORY;
	      if (mmu_on)
		store_long_parameter (buf + 1, addr & 0xfffffffc);
	      else
		store_long_parameter (buf + 1, addr & 0x7ffffffc);
	      store_long_parameter (buf + 5, 4);
	      serial_write (sdi_desc, buf, 9);
	      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
	      if (c != '-')
		recv_data (bp_data[i], 4);
	    }
	  return 0;
	}
    }

  error (_("Too many breakpoints"));
  return 1;
}

static int
m32r_remove_breakpoint (struct gdbarch *gdbarch,
			struct bp_target_info *bp_tgt)
{
  CORE_ADDR addr = bp_tgt->placed_address;
  int i;

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%s)\n",
			paddress (gdbarch, addr));

  for (i = 0; i < MAX_BREAKPOINTS; i++)
    {
      if (bp_address[i] == addr)
	{
	  bp_address[i] = 0xffffffff;
	  break;
	}
    }

  return 0;
}

static void
m32r_load (char *args, int from_tty)
{
  struct cleanup *old_chain;
  asection *section;
  bfd *pbfd;
  bfd_vma entry;
  char *filename;
  int quiet;
  int nostart;
  struct timeval start_time, end_time;
  unsigned long data_count;	/* Number of bytes transferred to memory.  */
  static RETSIGTYPE (*prev_sigint) ();

  /* for direct tcp connections, we can do a fast binary download.  */
  quiet = 0;
  nostart = 0;
  filename = NULL;

  while (*args != '\000')
    {
      char *arg;

      while (isspace (*args))
	args++;

      arg = args;

      while ((*args != '\000') && !isspace (*args))
	args++;

      if (*args != '\000')
	*args++ = '\000';

      if (*arg != '-')
	filename = arg;
      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
	quiet = 1;
      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
	nostart = 1;
      else
	error (_("Unknown option `%s'"), arg);
    }

  if (!filename)
    filename = get_exec_file (1);

  pbfd = bfd_openr (filename, gnutarget);
  if (pbfd == NULL)
    {
      perror_with_name (filename);
      return;
    }
  old_chain = make_cleanup_bfd_close (pbfd);

  if (!bfd_check_format (pbfd, bfd_object))
    error (_("\"%s\" is not an object file: %s"), filename,
	   bfd_errmsg (bfd_get_error ()));

  gettimeofday (&start_time, NULL);
  data_count = 0;

  interrupted = 0;
  prev_sigint = signal (SIGINT, gdb_cntrl_c);

  for (section = pbfd->sections; section; section = section->next)
    {
      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
	{
	  bfd_vma section_address;
	  bfd_size_type section_size;
	  file_ptr fptr;
	  int n;

	  section_address = bfd_section_lma (pbfd, section);
	  section_size = bfd_get_section_size (section);

	  if (!mmu_on)
	    {
	      if ((section_address & 0xa0000000) == 0x80000000)
		section_address &= 0x7fffffff;
	    }

	  if (!quiet)
	    printf_filtered ("[Loading section %s at 0x%lx (%d bytes)]\n",
			     bfd_get_section_name (pbfd, section),
			     (unsigned long) section_address,
			     (int) section_size);

	  fptr = 0;

	  data_count += section_size;

	  n = 0;
	  while (section_size > 0)
	    {
	      char unsigned buf[0x1000 + 9];
	      int count;

	      count = min (section_size, 0x1000);

	      buf[0] = SDI_WRITE_MEMORY;
	      store_long_parameter (buf + 1, section_address);
	      store_long_parameter (buf + 5, count);

	      bfd_get_section_contents (pbfd, section, buf + 9, fptr, count);
	      if (send_data (buf, count + 9) <= 0)
		error (_("Error while downloading %s section."),
		       bfd_get_section_name (pbfd, section));

	      if (!quiet)
		{
		  printf_unfiltered (".");
		  if (n++ > 60)
		    {
		      printf_unfiltered ("\n");
		      n = 0;
		    }
		  gdb_flush (gdb_stdout);
		}

	      section_address += count;
	      fptr += count;
	      section_size -= count;

	      if (interrupted)
		break;
	    }

	  if (!quiet && !interrupted)
	    {
	      printf_unfiltered ("done.\n");
	      gdb_flush (gdb_stdout);
	    }
	}

      if (interrupted)
	{
	  printf_unfiltered ("Interrupted.\n");
	  break;
	}
    }

  interrupted = 0;
  signal (SIGINT, prev_sigint);

  gettimeofday (&end_time, NULL);

  /* Make the PC point at the start address.  */
  if (exec_bfd)
    regcache_write_pc (get_current_regcache (),
		       bfd_get_start_address (exec_bfd));

  inferior_ptid = null_ptid;	/* No process now.  */
  delete_thread_silent (remote_m32r_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 (0);

  if (!nostart)
    {
      entry = bfd_get_start_address (pbfd);

      if (!quiet)
	printf_unfiltered ("[Starting %s at 0x%lx]\n", filename,
			   (unsigned long) entry);
    }

  print_transfer_performance (gdb_stdout, data_count, 0, &start_time,
			      &end_time);

  do_cleanups (old_chain);
}

static void
m32r_stop (ptid_t ptid)
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_stop()\n");

  send_cmd (SDI_STOP_CPU);

  return;
}


/* Tell whether this target can support a hardware breakpoint.  CNT
   is the number of hardware breakpoints already installed.  This
   implements the target_can_use_hardware_watchpoint macro.  */

static int
m32r_can_use_hw_watchpoint (int type, int cnt, int othertype)
{
  return sdi_desc != NULL && cnt < max_access_breaks;
}

/* Set a data watchpoint.  ADDR and LEN should be obvious.  TYPE is 0
   for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
   watchpoint.  */

static int
m32r_insert_watchpoint (CORE_ADDR addr, int len, int type,
			struct expression *cond)
{
  int i;

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_insert_watchpoint(%s,%d,%d)\n",
			paddress (target_gdbarch, addr), len, type);

  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
    {
      if (ab_address[i] == 0x00000000)
	{
	  ab_address[i] = addr;
	  ab_size[i] = len;
	  ab_type[i] = type;
	  return 0;
	}
    }

  error (_("Too many watchpoints"));
  return 1;
}

static int
m32r_remove_watchpoint (CORE_ADDR addr, int len, int type,
			struct expression *cond)
{
  int i;

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_remove_watchpoint(%s,%d,%d)\n",
			paddress (target_gdbarch, addr), len, type);

  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
    {
      if (ab_address[i] == addr)
	{
	  ab_address[i] = 0x00000000;
	  break;
	}
    }

  return 0;
}

static int
m32r_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
{
  int rc = 0;

  if (hit_watchpoint_addr != 0x00000000)
    {
      *addr_p = hit_watchpoint_addr;
      rc = 1;
    }
  return rc;
}

static int
m32r_stopped_by_watchpoint (void)
{
  CORE_ADDR addr;

  return m32r_stopped_data_address (&current_target, &addr);
}

/* Check to see if a thread is still alive.  */

static int
m32r_thread_alive (struct target_ops *ops, ptid_t ptid)
{
  if (ptid_equal (ptid, remote_m32r_ptid))
    /* The main task is always alive.  */
    return 1;

  return 0;
}

/* Convert a thread ID to a string.  Returns the string in a static
   buffer.  */

static char *
m32r_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
  static char buf[64];

  if (ptid_equal (remote_m32r_ptid, ptid))
    {
      xsnprintf (buf, sizeof buf, "Thread <main>");
      return buf;
    }

  return normal_pid_to_str (ptid);
}

static void
sdireset_command (char *args, int from_tty)
{
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n");

  send_cmd (SDI_OPEN);

  inferior_ptid = null_ptid;
  delete_thread_silent (remote_m32r_ptid);
}


static void
sdistatus_command (char *args, int from_tty)
{
  unsigned char buf[4096];
  int i, c;

  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n");

  if (!sdi_desc)
    return;

  send_cmd (SDI_STATUS);
  for (i = 0; i < 4096; i++)
    {
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      if (c < 0)
	return;
      buf[i] = c;
      if (c == 0)
	break;
    }

  printf_filtered ("%s", buf);
}


static void
debug_chaos_command (char *args, int from_tty)
{
  unsigned char buf[3];

  buf[0] = SDI_SET_ATTR;
  buf[1] = SDI_ATTR_CACHE;
  buf[2] = SDI_CACHE_TYPE_CHAOS;
  send_data (buf, 3);
}


static void
use_debug_dma_command (char *args, int from_tty)
{
  unsigned char buf[3];

  buf[0] = SDI_SET_ATTR;
  buf[1] = SDI_ATTR_MEM_ACCESS;
  buf[2] = SDI_MEM_ACCESS_DEBUG_DMA;
  send_data (buf, 3);
}

static void
use_mon_code_command (char *args, int from_tty)
{
  unsigned char buf[3];

  buf[0] = SDI_SET_ATTR;
  buf[1] = SDI_ATTR_MEM_ACCESS;
  buf[2] = SDI_MEM_ACCESS_MON_CODE;
  send_data (buf, 3);
}


static void
use_ib_breakpoints_command (char *args, int from_tty)
{
  use_ib_breakpoints = 1;
}

static void
use_dbt_breakpoints_command (char *args, int from_tty)
{
  use_ib_breakpoints = 0;
}

static int
m32r_return_one (struct target_ops *target)
{
  return 1;
}

/* Implementation of the to_has_execution method.  */

static int
m32r_has_execution (struct target_ops *target, ptid_t the_ptid)
{
  return 1;
}

/* Define the target subroutine names.  */

struct target_ops m32r_ops;

static void
init_m32r_ops (void)
{
  m32r_ops.to_shortname = "m32rsdi";
  m32r_ops.to_longname = "Remote M32R debugging over SDI interface";
  m32r_ops.to_doc = "Use an M32R board using SDI debugging protocol.";
  m32r_ops.to_open = m32r_open;
  m32r_ops.to_close = m32r_close;
  m32r_ops.to_detach = m32r_detach;
  m32r_ops.to_resume = m32r_resume;
  m32r_ops.to_wait = m32r_wait;
  m32r_ops.to_fetch_registers = m32r_fetch_register;
  m32r_ops.to_store_registers = m32r_store_register;
  m32r_ops.to_prepare_to_store = m32r_prepare_to_store;
  m32r_ops.deprecated_xfer_memory = m32r_xfer_memory;
  m32r_ops.to_files_info = m32r_files_info;
  m32r_ops.to_insert_breakpoint = m32r_insert_breakpoint;
  m32r_ops.to_remove_breakpoint = m32r_remove_breakpoint;
  m32r_ops.to_can_use_hw_breakpoint = m32r_can_use_hw_watchpoint;
  m32r_ops.to_insert_watchpoint = m32r_insert_watchpoint;
  m32r_ops.to_remove_watchpoint = m32r_remove_watchpoint;
  m32r_ops.to_stopped_by_watchpoint = m32r_stopped_by_watchpoint;
  m32r_ops.to_stopped_data_address = m32r_stopped_data_address;
  m32r_ops.to_kill = m32r_kill;
  m32r_ops.to_load = m32r_load;
  m32r_ops.to_create_inferior = m32r_create_inferior;
  m32r_ops.to_mourn_inferior = m32r_mourn_inferior;
  m32r_ops.to_stop = m32r_stop;
  m32r_ops.to_log_command = serial_log_command;
  m32r_ops.to_thread_alive = m32r_thread_alive;
  m32r_ops.to_pid_to_str = m32r_pid_to_str;
  m32r_ops.to_stratum = process_stratum;
  m32r_ops.to_has_all_memory = m32r_return_one;
  m32r_ops.to_has_memory = m32r_return_one;
  m32r_ops.to_has_stack = m32r_return_one;
  m32r_ops.to_has_registers = m32r_return_one;
  m32r_ops.to_has_execution = m32r_has_execution;
  m32r_ops.to_magic = OPS_MAGIC;
};


extern initialize_file_ftype _initialize_remote_m32r;

void
_initialize_remote_m32r (void)
{
  int i;

  init_m32r_ops ();

  /* Initialize breakpoints.  */
  for (i = 0; i < MAX_BREAKPOINTS; i++)
    bp_address[i] = 0xffffffff;

  /* Initialize access breaks.  */
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
    ab_address[i] = 0x00000000;

  add_target (&m32r_ops);

  add_com ("sdireset", class_obscure, sdireset_command,
	   _("Reset SDI connection."));

  add_com ("sdistatus", class_obscure, sdistatus_command,
	   _("Show status of SDI connection."));

  add_com ("debug_chaos", class_obscure, debug_chaos_command,
	   _("Debug M32R/Chaos."));

  add_com ("use_debug_dma", class_obscure, use_debug_dma_command,
	   _("Use debug DMA mem access."));
  add_com ("use_mon_code", class_obscure, use_mon_code_command,
	   _("Use mon code mem access."));

  add_com ("use_ib_break", class_obscure, use_ib_breakpoints_command,
	   _("Set breakpoints by IB break."));
  add_com ("use_dbt_break", class_obscure, use_dbt_breakpoints_command,
	   _("Set breakpoints by dbt."));

  /* Yes, 42000 is arbitrary.  The only sense out of it, is that it
     isn't 0.  */
  remote_m32r_ptid = ptid_build (42000, 0, 42000);
}
