OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [remote-m32r-sdi.c] - Diff between revs 827 and 840

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 827 Rev 840
/* Remote debugging interface for M32R/SDI.
/* Remote debugging interface for M32R/SDI.
 
 
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   Contributed by Renesas Technology Co.
   Contributed by Renesas Technology Co.
   Written by Kei Sakamoto <sakamoto.kei@renesas.com>.
   Written by Kei Sakamoto <sakamoto.kei@renesas.com>.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#include "defs.h"
#include "defs.h"
#include "gdbcmd.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "gdbcore.h"
#include "inferior.h"
#include "inferior.h"
#include "target.h"
#include "target.h"
#include "regcache.h"
#include "regcache.h"
#include "gdb_string.h"
#include "gdb_string.h"
#include <ctype.h>
#include <ctype.h>
#include <signal.h>
#include <signal.h>
#ifdef __MINGW32__
#ifdef __MINGW32__
#include <winsock.h>
#include <winsock.h>
#else
#else
#include <netinet/in.h>
#include <netinet/in.h>
#endif
#endif
#include <sys/types.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/time.h>
#include <signal.h>
#include <signal.h>
#include <time.h>
#include <time.h>
 
 
 
 
#include "serial.h"
#include "serial.h"
 
 
/* Descriptor for I/O to remote machine.  */
/* Descriptor for I/O to remote machine.  */
 
 
static struct serial *sdi_desc = NULL;
static struct serial *sdi_desc = NULL;
 
 
#define SDI_TIMEOUT 30
#define SDI_TIMEOUT 30
 
 
 
 
#define SDIPORT 3232
#define SDIPORT 3232
 
 
static char chip_name[64];
static char chip_name[64];
 
 
static int step_mode;
static int step_mode;
static unsigned long last_pc_addr = 0xffffffff;
static unsigned long last_pc_addr = 0xffffffff;
static unsigned char last_pc_addr_data[2];
static unsigned char last_pc_addr_data[2];
 
 
static int mmu_on = 0;
static int mmu_on = 0;
 
 
static int use_ib_breakpoints = 1;
static int use_ib_breakpoints = 1;
 
 
#define MAX_BREAKPOINTS 1024
#define MAX_BREAKPOINTS 1024
static int max_ib_breakpoints;
static int max_ib_breakpoints;
static unsigned long bp_address[MAX_BREAKPOINTS];
static unsigned long bp_address[MAX_BREAKPOINTS];
static unsigned char bp_data[MAX_BREAKPOINTS][4];
static unsigned char bp_data[MAX_BREAKPOINTS][4];
 
 
/* dbt -> nop */
/* dbt -> nop */
static const unsigned char dbt_bp_entry[] = {
static const unsigned char dbt_bp_entry[] = {
  0x10, 0xe0, 0x70, 0x00
  0x10, 0xe0, 0x70, 0x00
};
};
 
 
#define MAX_ACCESS_BREAKS 4
#define MAX_ACCESS_BREAKS 4
static int max_access_breaks;
static int max_access_breaks;
static unsigned long ab_address[MAX_ACCESS_BREAKS];
static unsigned long ab_address[MAX_ACCESS_BREAKS];
static unsigned int ab_type[MAX_ACCESS_BREAKS];
static unsigned int ab_type[MAX_ACCESS_BREAKS];
static unsigned int ab_size[MAX_ACCESS_BREAKS];
static unsigned int ab_size[MAX_ACCESS_BREAKS];
static CORE_ADDR hit_watchpoint_addr = 0;
static CORE_ADDR hit_watchpoint_addr = 0;
 
 
static int interrupted = 0;
static int interrupted = 0;
 
 
/* Forward data declarations */
/* Forward data declarations */
extern struct target_ops m32r_ops;
extern struct target_ops m32r_ops;
 
 
 
 
/* Commands */
/* Commands */
#define SDI_OPEN                 1
#define SDI_OPEN                 1
#define SDI_CLOSE                2
#define SDI_CLOSE                2
#define SDI_RELEASE              3
#define SDI_RELEASE              3
#define SDI_READ_CPU_REG         4
#define SDI_READ_CPU_REG         4
#define SDI_WRITE_CPU_REG        5
#define SDI_WRITE_CPU_REG        5
#define SDI_READ_MEMORY          6
#define SDI_READ_MEMORY          6
#define SDI_WRITE_MEMORY         7
#define SDI_WRITE_MEMORY         7
#define SDI_EXEC_CPU             8
#define SDI_EXEC_CPU             8
#define SDI_STOP_CPU             9
#define SDI_STOP_CPU             9
#define SDI_WAIT_FOR_READY      10
#define SDI_WAIT_FOR_READY      10
#define SDI_GET_ATTR            11
#define SDI_GET_ATTR            11
#define SDI_SET_ATTR            12
#define SDI_SET_ATTR            12
#define SDI_STATUS              13
#define SDI_STATUS              13
 
 
/* Attributes */
/* Attributes */
#define SDI_ATTR_NAME            1
#define SDI_ATTR_NAME            1
#define SDI_ATTR_BRK             2
#define SDI_ATTR_BRK             2
#define SDI_ATTR_ABRK            3
#define SDI_ATTR_ABRK            3
#define SDI_ATTR_CACHE           4
#define SDI_ATTR_CACHE           4
#define SDI_CACHE_TYPE_M32102    0
#define SDI_CACHE_TYPE_M32102    0
#define SDI_CACHE_TYPE_CHAOS     1
#define SDI_CACHE_TYPE_CHAOS     1
#define SDI_ATTR_MEM_ACCESS      5
#define SDI_ATTR_MEM_ACCESS      5
#define SDI_MEM_ACCESS_DEBUG_DMA 0
#define SDI_MEM_ACCESS_DEBUG_DMA 0
#define SDI_MEM_ACCESS_MON_CODE  1
#define SDI_MEM_ACCESS_MON_CODE  1
 
 
/* Registers */
/* Registers */
#define SDI_REG_R0               0
#define SDI_REG_R0               0
#define SDI_REG_R1               1
#define SDI_REG_R1               1
#define SDI_REG_R2               2
#define SDI_REG_R2               2
#define SDI_REG_R3               3
#define SDI_REG_R3               3
#define SDI_REG_R4               4
#define SDI_REG_R4               4
#define SDI_REG_R5               5
#define SDI_REG_R5               5
#define SDI_REG_R6               6
#define SDI_REG_R6               6
#define SDI_REG_R7               7
#define SDI_REG_R7               7
#define SDI_REG_R8               8
#define SDI_REG_R8               8
#define SDI_REG_R9               9
#define SDI_REG_R9               9
#define SDI_REG_R10             10
#define SDI_REG_R10             10
#define SDI_REG_R11             11
#define SDI_REG_R11             11
#define SDI_REG_R12             12
#define SDI_REG_R12             12
#define SDI_REG_FP              13
#define SDI_REG_FP              13
#define SDI_REG_LR              14
#define SDI_REG_LR              14
#define SDI_REG_SP              15
#define SDI_REG_SP              15
#define SDI_REG_PSW             16
#define SDI_REG_PSW             16
#define SDI_REG_CBR             17
#define SDI_REG_CBR             17
#define SDI_REG_SPI             18
#define SDI_REG_SPI             18
#define SDI_REG_SPU             19
#define SDI_REG_SPU             19
#define SDI_REG_CR4             20
#define SDI_REG_CR4             20
#define SDI_REG_EVB             21
#define SDI_REG_EVB             21
#define SDI_REG_BPC             22
#define SDI_REG_BPC             22
#define SDI_REG_CR7             23
#define SDI_REG_CR7             23
#define SDI_REG_BBPSW           24
#define SDI_REG_BBPSW           24
#define SDI_REG_CR9             25
#define SDI_REG_CR9             25
#define SDI_REG_CR10            26
#define SDI_REG_CR10            26
#define SDI_REG_CR11            27
#define SDI_REG_CR11            27
#define SDI_REG_CR12            28
#define SDI_REG_CR12            28
#define SDI_REG_WR              29
#define SDI_REG_WR              29
#define SDI_REG_BBPC            30
#define SDI_REG_BBPC            30
#define SDI_REG_PBP             31
#define SDI_REG_PBP             31
#define SDI_REG_ACCH            32
#define SDI_REG_ACCH            32
#define SDI_REG_ACCL            33
#define SDI_REG_ACCL            33
#define SDI_REG_ACC1H           34
#define SDI_REG_ACC1H           34
#define SDI_REG_ACC1L           35
#define SDI_REG_ACC1L           35
 
 
 
 
/* Low level communication functions */
/* Low level communication functions */
 
 
/* Check an ack packet from the target */
/* Check an ack packet from the target */
static int
static int
get_ack (void)
get_ack (void)
{
{
  int c;
  int c;
 
 
  if (!sdi_desc)
  if (!sdi_desc)
    return -1;
    return -1;
 
 
  c = serial_readchar (sdi_desc, SDI_TIMEOUT);
  c = serial_readchar (sdi_desc, SDI_TIMEOUT);
 
 
  if (c < 0)
  if (c < 0)
    return -1;
    return -1;
 
 
  if (c != '+')                 /* error */
  if (c != '+')                 /* error */
    return -1;
    return -1;
 
 
  return 0;
  return 0;
}
}
 
 
/* Send data to the target and check an ack packet */
/* Send data to the target and check an ack packet */
static int
static int
send_data (void *buf, int len)
send_data (void *buf, int len)
{
{
  int ret;
  int ret;
 
 
  if (!sdi_desc)
  if (!sdi_desc)
    return -1;
    return -1;
 
 
  if (serial_write (sdi_desc, buf, len) != 0)
  if (serial_write (sdi_desc, buf, len) != 0)
    return -1;
    return -1;
 
 
  if (get_ack () == -1)
  if (get_ack () == -1)
    return -1;
    return -1;
 
 
  return len;
  return len;
}
}
 
 
/* Receive data from the target */
/* Receive data from the target */
static int
static int
recv_data (void *buf, int len)
recv_data (void *buf, int len)
{
{
  int total = 0;
  int total = 0;
  int c;
  int c;
 
 
  if (!sdi_desc)
  if (!sdi_desc)
    return -1;
    return -1;
 
 
  while (total < len)
  while (total < len)
    {
    {
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
 
 
      if (c < 0)
      if (c < 0)
        return -1;
        return -1;
 
 
      ((unsigned char *) buf)[total++] = c;
      ((unsigned char *) buf)[total++] = c;
    }
    }
 
 
  return len;
  return len;
}
}
 
 
/* Store unsigned long parameter on packet */
/* Store unsigned long parameter on packet */
static void
static void
store_long_parameter (void *buf, long val)
store_long_parameter (void *buf, long val)
{
{
  val = htonl (val);
  val = htonl (val);
  memcpy (buf, &val, 4);
  memcpy (buf, &val, 4);
}
}
 
 
static int
static int
send_cmd (unsigned char cmd)
send_cmd (unsigned char cmd)
{
{
  unsigned char buf[1];
  unsigned char buf[1];
  buf[0] = cmd;
  buf[0] = cmd;
  return send_data (buf, 1);
  return send_data (buf, 1);
}
}
 
 
static int
static int
send_one_arg_cmd (unsigned char cmd, unsigned char arg1)
send_one_arg_cmd (unsigned char cmd, unsigned char arg1)
{
{
  unsigned char buf[2];
  unsigned char buf[2];
  buf[0] = cmd;
  buf[0] = cmd;
  buf[1] = arg1;
  buf[1] = arg1;
  return send_data (buf, 2);
  return send_data (buf, 2);
}
}
 
 
static int
static int
send_two_arg_cmd (unsigned char cmd, unsigned char arg1, unsigned long arg2)
send_two_arg_cmd (unsigned char cmd, unsigned char arg1, unsigned long arg2)
{
{
  unsigned char buf[6];
  unsigned char buf[6];
  buf[0] = cmd;
  buf[0] = cmd;
  buf[1] = arg1;
  buf[1] = arg1;
  store_long_parameter (buf + 2, arg2);
  store_long_parameter (buf + 2, arg2);
  return send_data (buf, 6);
  return send_data (buf, 6);
}
}
 
 
static int
static int
send_three_arg_cmd (unsigned char cmd, unsigned long arg1, unsigned long arg2,
send_three_arg_cmd (unsigned char cmd, unsigned long arg1, unsigned long arg2,
                    unsigned long arg3)
                    unsigned long arg3)
{
{
  unsigned char buf[13];
  unsigned char buf[13];
  buf[0] = cmd;
  buf[0] = cmd;
  store_long_parameter (buf + 1, arg1);
  store_long_parameter (buf + 1, arg1);
  store_long_parameter (buf + 5, arg2);
  store_long_parameter (buf + 5, arg2);
  store_long_parameter (buf + 9, arg3);
  store_long_parameter (buf + 9, arg3);
  return send_data (buf, 13);
  return send_data (buf, 13);
}
}
 
 
static unsigned char
static unsigned char
recv_char_data (void)
recv_char_data (void)
{
{
  unsigned char val;
  unsigned char val;
  recv_data (&val, 1);
  recv_data (&val, 1);
  return val;
  return val;
}
}
 
 
static unsigned long
static unsigned long
recv_long_data (void)
recv_long_data (void)
{
{
  unsigned long val;
  unsigned long val;
  recv_data (&val, 4);
  recv_data (&val, 4);
  return ntohl (val);
  return ntohl (val);
}
}
 
 
 
 
/* Check if MMU is on */
/* Check if MMU is on */
static void
static void
check_mmu_status (void)
check_mmu_status (void)
{
{
  unsigned long val;
  unsigned long val;
 
 
  /* Read PC address */
  /* Read PC address */
  if (send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BPC) == -1)
  if (send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BPC) == -1)
    return;
    return;
  val = recv_long_data ();
  val = recv_long_data ();
  if ((val & 0xc0000000) == 0x80000000)
  if ((val & 0xc0000000) == 0x80000000)
    {
    {
      mmu_on = 1;
      mmu_on = 1;
      return;
      return;
    }
    }
 
 
  /* Read EVB address */
  /* Read EVB address */
  if (send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_EVB) == -1)
  if (send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_EVB) == -1)
    return;
    return;
  val = recv_long_data ();
  val = recv_long_data ();
  if ((val & 0xc0000000) == 0x80000000)
  if ((val & 0xc0000000) == 0x80000000)
    {
    {
      mmu_on = 1;
      mmu_on = 1;
      return;
      return;
    }
    }
 
 
  mmu_on = 0;
  mmu_on = 0;
}
}
 
 
 
 
/* This is called not only when we first attach, but also when the
/* This is called not only when we first attach, but also when the
   user types "run" after having attached.  */
   user types "run" after having attached.  */
static void
static void
m32r_create_inferior (char *execfile, char *args, char **env, int from_tty)
m32r_create_inferior (char *execfile, char *args, char **env, int from_tty)
{
{
  CORE_ADDR entry_pt;
  CORE_ADDR entry_pt;
 
 
  if (args && *args)
  if (args && *args)
    error (_("Cannot pass arguments to remote STDEBUG process"));
    error (_("Cannot pass arguments to remote STDEBUG process"));
 
 
  if (execfile == 0 || exec_bfd == 0)
  if (execfile == 0 || exec_bfd == 0)
    error (_("No executable file specified"));
    error (_("No executable file specified"));
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_create_inferior(%s,%s)\n", execfile,
    fprintf_unfiltered (gdb_stdlog, "m32r_create_inferior(%s,%s)\n", execfile,
                        args);
                        args);
 
 
  entry_pt = bfd_get_start_address (exec_bfd);
  entry_pt = bfd_get_start_address (exec_bfd);
 
 
  /* The "process" (board) is already stopped awaiting our commands, and
  /* The "process" (board) is already stopped awaiting our commands, and
     the program is already downloaded.  We just set its PC and go.  */
     the program is already downloaded.  We just set its PC and go.  */
 
 
  clear_proceed_status ();
  clear_proceed_status ();
 
 
  /* Tell wait_for_inferior that we've started a new process.  */
  /* Tell wait_for_inferior that we've started a new process.  */
  init_wait_for_inferior ();
  init_wait_for_inferior ();
 
 
  /* Set up the "saved terminal modes" of the inferior
  /* Set up the "saved terminal modes" of the inferior
     based on what modes we are starting it with.  */
     based on what modes we are starting it with.  */
  target_terminal_init ();
  target_terminal_init ();
 
 
  /* Install inferior's terminal modes.  */
  /* Install inferior's terminal modes.  */
  target_terminal_inferior ();
  target_terminal_inferior ();
 
 
  write_pc (entry_pt);
  write_pc (entry_pt);
}
}
 
 
/* Open a connection to a remote debugger.
/* Open a connection to a remote debugger.
   NAME is the filename used for communication.  */
   NAME is the filename used for communication.  */
 
 
static void
static void
m32r_open (char *args, int from_tty)
m32r_open (char *args, int from_tty)
{
{
  struct hostent *host_ent;
  struct hostent *host_ent;
  struct sockaddr_in server_addr;
  struct sockaddr_in server_addr;
  char *port_str, hostname[256];
  char *port_str, hostname[256];
  int port;
  int port;
  int i, n;
  int i, n;
  int yes = 1;
  int yes = 1;
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_open(%d)\n", from_tty);
    fprintf_unfiltered (gdb_stdlog, "m32r_open(%d)\n", from_tty);
 
 
  target_preopen (from_tty);
  target_preopen (from_tty);
 
 
  push_target (&m32r_ops);
  push_target (&m32r_ops);
 
 
  if (args == NULL)
  if (args == NULL)
    sprintf (hostname, "localhost:%d", SDIPORT);
    sprintf (hostname, "localhost:%d", SDIPORT);
  else
  else
    {
    {
      port_str = strchr (args, ':');
      port_str = strchr (args, ':');
      if (port_str == NULL)
      if (port_str == NULL)
        sprintf (hostname, "%s:%d", args, SDIPORT);
        sprintf (hostname, "%s:%d", args, SDIPORT);
      else
      else
        strcpy (hostname, args);
        strcpy (hostname, args);
    }
    }
 
 
  sdi_desc = serial_open (hostname);
  sdi_desc = serial_open (hostname);
  if (!sdi_desc)
  if (!sdi_desc)
    error (_("Connection refused."));
    error (_("Connection refused."));
 
 
  if (get_ack () == -1)
  if (get_ack () == -1)
    error (_("Cannot connect to SDI target."));
    error (_("Cannot connect to SDI target."));
 
 
  if (send_cmd (SDI_OPEN) == -1)
  if (send_cmd (SDI_OPEN) == -1)
    error (_("Cannot connect to SDI target."));
    error (_("Cannot connect to SDI target."));
 
 
  /* Get maximum number of ib breakpoints */
  /* Get maximum number of ib breakpoints */
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_BRK);
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_BRK);
  max_ib_breakpoints = recv_char_data ();
  max_ib_breakpoints = recv_char_data ();
  if (remote_debug)
  if (remote_debug)
    printf_filtered ("Max IB Breakpoints = %d\n", max_ib_breakpoints);
    printf_filtered ("Max IB Breakpoints = %d\n", max_ib_breakpoints);
 
 
  /* Initialize breakpoints. */
  /* Initialize breakpoints. */
  for (i = 0; i < MAX_BREAKPOINTS; i++)
  for (i = 0; i < MAX_BREAKPOINTS; i++)
    bp_address[i] = 0xffffffff;
    bp_address[i] = 0xffffffff;
 
 
  /* Get maximum number of access breaks. */
  /* Get maximum number of access breaks. */
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_ABRK);
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_ABRK);
  max_access_breaks = recv_char_data ();
  max_access_breaks = recv_char_data ();
  if (remote_debug)
  if (remote_debug)
    printf_filtered ("Max Access Breaks = %d\n", max_access_breaks);
    printf_filtered ("Max Access Breaks = %d\n", max_access_breaks);
 
 
  /* Initialize access breask. */
  /* Initialize access breask. */
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
    ab_address[i] = 0x00000000;
    ab_address[i] = 0x00000000;
 
 
  check_mmu_status ();
  check_mmu_status ();
 
 
  /* Get the name of chip on target board. */
  /* Get the name of chip on target board. */
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_NAME);
  send_one_arg_cmd (SDI_GET_ATTR, SDI_ATTR_NAME);
  recv_data (chip_name, 64);
  recv_data (chip_name, 64);
 
 
  if (from_tty)
  if (from_tty)
    printf_filtered ("Remote %s connected to %s\n", target_shortname,
    printf_filtered ("Remote %s connected to %s\n", target_shortname,
                     chip_name);
                     chip_name);
}
}
 
 
/* Close out all files and local state before this target loses control. */
/* Close out all files and local state before this target loses control. */
 
 
static void
static void
m32r_close (int quitting)
m32r_close (int quitting)
{
{
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_close(%d)\n", quitting);
    fprintf_unfiltered (gdb_stdlog, "m32r_close(%d)\n", quitting);
 
 
  if (sdi_desc)
  if (sdi_desc)
    {
    {
      send_cmd (SDI_CLOSE);
      send_cmd (SDI_CLOSE);
      serial_close (sdi_desc);
      serial_close (sdi_desc);
      sdi_desc = NULL;
      sdi_desc = NULL;
    }
    }
 
 
  inferior_ptid = null_ptid;
  inferior_ptid = null_ptid;
  return;
  return;
}
}
 
 
/* Tell the remote machine to resume.  */
/* Tell the remote machine to resume.  */
 
 
static void
static void
m32r_resume (ptid_t ptid, int step, enum target_signal sig)
m32r_resume (ptid_t ptid, int step, enum target_signal sig)
{
{
  unsigned long pc_addr, bp_addr, ab_addr;
  unsigned long pc_addr, bp_addr, ab_addr;
  int ib_breakpoints;
  int ib_breakpoints;
  unsigned char buf[13];
  unsigned char buf[13];
  int i;
  int i;
 
 
  if (remote_debug)
  if (remote_debug)
    {
    {
      if (step)
      if (step)
        fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(step)\n");
        fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(step)\n");
      else
      else
        fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(cont)\n");
        fprintf_unfiltered (gdb_stdlog, "\nm32r_resume(cont)\n");
    }
    }
 
 
  check_mmu_status ();
  check_mmu_status ();
 
 
  pc_addr = read_pc ();
  pc_addr = read_pc ();
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "pc <= 0x%lx\n", pc_addr);
    fprintf_unfiltered (gdb_stdlog, "pc <= 0x%lx\n", pc_addr);
 
 
  /* At pc address there is a parallel instruction with +2 offset,
  /* At pc address there is a parallel instruction with +2 offset,
     so we have to make it a serial instruction or avoid it. */
     so we have to make it a serial instruction or avoid it. */
  if (pc_addr == last_pc_addr)
  if (pc_addr == last_pc_addr)
    {
    {
      /* Avoid a parallel nop. */
      /* Avoid a parallel nop. */
      if (last_pc_addr_data[0] == 0xf0 && last_pc_addr_data[1] == 0x00)
      if (last_pc_addr_data[0] == 0xf0 && last_pc_addr_data[1] == 0x00)
        {
        {
          pc_addr += 2;
          pc_addr += 2;
          /* Now we can forget this instruction. */
          /* Now we can forget this instruction. */
          last_pc_addr = 0xffffffff;
          last_pc_addr = 0xffffffff;
        }
        }
      /* Clear a parallel bit. */
      /* Clear a parallel bit. */
      else
      else
        {
        {
          buf[0] = SDI_WRITE_MEMORY;
          buf[0] = SDI_WRITE_MEMORY;
          if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
          if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
            store_long_parameter (buf + 1, pc_addr);
            store_long_parameter (buf + 1, pc_addr);
          else
          else
            store_long_parameter (buf + 1, pc_addr - 1);
            store_long_parameter (buf + 1, pc_addr - 1);
          store_long_parameter (buf + 5, 1);
          store_long_parameter (buf + 5, 1);
          buf[9] = last_pc_addr_data[0] & 0x7f;
          buf[9] = last_pc_addr_data[0] & 0x7f;
          send_data (buf, 10);
          send_data (buf, 10);
        }
        }
    }
    }
 
 
  /* Set PC. */
  /* Set PC. */
  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BPC, pc_addr);
  send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BPC, pc_addr);
 
 
  /* step mode. */
  /* step mode. */
  step_mode = step;
  step_mode = step;
  if (step)
  if (step)
    {
    {
      /* Set PBP. */
      /* Set PBP. */
      send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PBP, pc_addr | 1);
      send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PBP, pc_addr | 1);
    }
    }
  else
  else
    {
    {
      /* Unset PBP. */
      /* Unset PBP. */
      send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PBP, 0x00000000);
      send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PBP, 0x00000000);
    }
    }
 
 
  if (use_ib_breakpoints)
  if (use_ib_breakpoints)
    ib_breakpoints = max_ib_breakpoints;
    ib_breakpoints = max_ib_breakpoints;
  else
  else
    ib_breakpoints = 0;
    ib_breakpoints = 0;
 
 
  /* Set ib breakpoints. */
  /* Set ib breakpoints. */
  for (i = 0; i < ib_breakpoints; i++)
  for (i = 0; i < ib_breakpoints; i++)
    {
    {
      bp_addr = bp_address[i];
      bp_addr = bp_address[i];
 
 
      if (bp_addr == 0xffffffff)
      if (bp_addr == 0xffffffff)
        continue;
        continue;
 
 
      /* Set PBP. */
      /* Set PBP. */
      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
        send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
        send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
                            0x00000006);
                            0x00000006);
      else
      else
        send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
        send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
                            0x06000000);
                            0x06000000);
 
 
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8080 + 4 * i, 4, bp_addr);
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8080 + 4 * i, 4, bp_addr);
    }
    }
 
 
  /* Set dbt breakpoints. */
  /* Set dbt breakpoints. */
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
    {
    {
      bp_addr = bp_address[i];
      bp_addr = bp_address[i];
 
 
      if (bp_addr == 0xffffffff)
      if (bp_addr == 0xffffffff)
        continue;
        continue;
 
 
      if (!mmu_on)
      if (!mmu_on)
        bp_addr &= 0x7fffffff;
        bp_addr &= 0x7fffffff;
 
 
      /* Write DBT instruction. */
      /* Write DBT instruction. */
      buf[0] = SDI_WRITE_MEMORY;
      buf[0] = SDI_WRITE_MEMORY;
      store_long_parameter (buf + 1, (bp_addr & 0xfffffffc));
      store_long_parameter (buf + 1, (bp_addr & 0xfffffffc));
      store_long_parameter (buf + 5, 4);
      store_long_parameter (buf + 5, 4);
      if ((bp_addr & 2) == 0 && bp_addr != (pc_addr & 0xfffffffc))
      if ((bp_addr & 2) == 0 && bp_addr != (pc_addr & 0xfffffffc))
        {
        {
          if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
          if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
            {
            {
              buf[9] = dbt_bp_entry[0];
              buf[9] = dbt_bp_entry[0];
              buf[10] = dbt_bp_entry[1];
              buf[10] = dbt_bp_entry[1];
              buf[11] = dbt_bp_entry[2];
              buf[11] = dbt_bp_entry[2];
              buf[12] = dbt_bp_entry[3];
              buf[12] = dbt_bp_entry[3];
            }
            }
          else
          else
            {
            {
              buf[9] = dbt_bp_entry[3];
              buf[9] = dbt_bp_entry[3];
              buf[10] = dbt_bp_entry[2];
              buf[10] = dbt_bp_entry[2];
              buf[11] = dbt_bp_entry[1];
              buf[11] = dbt_bp_entry[1];
              buf[12] = dbt_bp_entry[0];
              buf[12] = dbt_bp_entry[0];
            }
            }
        }
        }
      else
      else
        {
        {
          if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
          if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
            {
            {
              if ((bp_addr & 2) == 0)
              if ((bp_addr & 2) == 0)
                {
                {
                  buf[9] = dbt_bp_entry[0];
                  buf[9] = dbt_bp_entry[0];
                  buf[10] = dbt_bp_entry[1];
                  buf[10] = dbt_bp_entry[1];
                  buf[11] = bp_data[i][2] & 0x7f;
                  buf[11] = bp_data[i][2] & 0x7f;
                  buf[12] = bp_data[i][3];
                  buf[12] = bp_data[i][3];
                }
                }
              else
              else
                {
                {
                  buf[9] = bp_data[i][0];
                  buf[9] = bp_data[i][0];
                  buf[10] = bp_data[i][1];
                  buf[10] = bp_data[i][1];
                  buf[11] = dbt_bp_entry[0];
                  buf[11] = dbt_bp_entry[0];
                  buf[12] = dbt_bp_entry[1];
                  buf[12] = dbt_bp_entry[1];
                }
                }
            }
            }
          else
          else
            {
            {
              if ((bp_addr & 2) == 0)
              if ((bp_addr & 2) == 0)
                {
                {
                  buf[9] = bp_data[i][0];
                  buf[9] = bp_data[i][0];
                  buf[10] = bp_data[i][1] & 0x7f;
                  buf[10] = bp_data[i][1] & 0x7f;
                  buf[11] = dbt_bp_entry[1];
                  buf[11] = dbt_bp_entry[1];
                  buf[12] = dbt_bp_entry[0];
                  buf[12] = dbt_bp_entry[0];
                }
                }
              else
              else
                {
                {
                  buf[9] = dbt_bp_entry[1];
                  buf[9] = dbt_bp_entry[1];
                  buf[10] = dbt_bp_entry[0];
                  buf[10] = dbt_bp_entry[0];
                  buf[11] = bp_data[i][2];
                  buf[11] = bp_data[i][2];
                  buf[12] = bp_data[i][3];
                  buf[12] = bp_data[i][3];
                }
                }
            }
            }
        }
        }
      send_data (buf, 13);
      send_data (buf, 13);
    }
    }
 
 
  /* Set access breaks. */
  /* Set access breaks. */
  for (i = 0; i < max_access_breaks; i++)
  for (i = 0; i < max_access_breaks; i++)
    {
    {
      ab_addr = ab_address[i];
      ab_addr = ab_address[i];
 
 
      if (ab_addr == 0x00000000)
      if (ab_addr == 0x00000000)
        continue;
        continue;
 
 
      /* DBC register */
      /* DBC register */
      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
        {
        {
          switch (ab_type[i])
          switch (ab_type[i])
            {
            {
            case 0:              /* write watch */
            case 0:              /* write watch */
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
                                  0x00000086);
                                  0x00000086);
              break;
              break;
            case 1:             /* read watch */
            case 1:             /* read watch */
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
                                  0x00000046);
                                  0x00000046);
              break;
              break;
            case 2:             /* access watch */
            case 2:             /* access watch */
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
                                  0x00000006);
                                  0x00000006);
              break;
              break;
            }
            }
        }
        }
      else
      else
        {
        {
          switch (ab_type[i])
          switch (ab_type[i])
            {
            {
            case 0:              /* write watch */
            case 0:              /* write watch */
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
                                  0x86000000);
                                  0x86000000);
              break;
              break;
            case 1:             /* read watch */
            case 1:             /* read watch */
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
                                  0x46000000);
                                  0x46000000);
              break;
              break;
            case 2:             /* access watch */
            case 2:             /* access watch */
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
              send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
                                  0x06000000);
                                  0x06000000);
              break;
              break;
            }
            }
        }
        }
 
 
      /* DBAH register */
      /* DBAH register */
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8180 + 4 * i, 4, ab_addr);
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8180 + 4 * i, 4, ab_addr);
 
 
      /* DBAL register */
      /* DBAL register */
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8200 + 4 * i, 4,
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8200 + 4 * i, 4,
                          0xffffffff);
                          0xffffffff);
 
 
      /* DBD register */
      /* DBD register */
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8280 + 4 * i, 4,
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8280 + 4 * i, 4,
                          0x00000000);
                          0x00000000);
 
 
      /* DBDM register */
      /* DBDM register */
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8300 + 4 * i, 4,
      send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8300 + 4 * i, 4,
                          0x00000000);
                          0x00000000);
    }
    }
 
 
  /* Resume program. */
  /* Resume program. */
  send_cmd (SDI_EXEC_CPU);
  send_cmd (SDI_EXEC_CPU);
 
 
  /* Without this, some commands which require an active target (such as kill)
  /* 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
     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
     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
     target is active.  These functions should be split out into seperate
     variables, especially since GDB will someday have a notion of debugging
     variables, especially since GDB will someday have a notion of debugging
     several processes.  */
     several processes.  */
  inferior_ptid = pid_to_ptid (32);
  inferior_ptid = pid_to_ptid (32);
 
 
  return;
  return;
}
}
 
 
/* Wait until the remote machine stops, then return,
/* Wait until the remote machine stops, then return,
   storing status in STATUS just as `wait' would.  */
   storing status in STATUS just as `wait' would.  */
 
 
static void
static void
gdb_cntrl_c (int signo)
gdb_cntrl_c (int signo)
{
{
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "interrupt\n");
    fprintf_unfiltered (gdb_stdlog, "interrupt\n");
  interrupted = 1;
  interrupted = 1;
}
}
 
 
static ptid_t
static ptid_t
m32r_wait (ptid_t ptid, struct target_waitstatus *status)
m32r_wait (ptid_t ptid, struct target_waitstatus *status)
{
{
  static RETSIGTYPE (*prev_sigint) ();
  static RETSIGTYPE (*prev_sigint) ();
  unsigned long bp_addr, pc_addr;
  unsigned long bp_addr, pc_addr;
  int ib_breakpoints;
  int ib_breakpoints;
  long i;
  long i;
  unsigned char buf[13];
  unsigned char buf[13];
  unsigned long val;
  unsigned long val;
  int ret, c;
  int ret, c;
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_wait()\n");
    fprintf_unfiltered (gdb_stdlog, "m32r_wait()\n");
 
 
  status->kind = TARGET_WAITKIND_EXITED;
  status->kind = TARGET_WAITKIND_EXITED;
  status->value.sig = 0;
  status->value.sig = 0;
 
 
  interrupted = 0;
  interrupted = 0;
  prev_sigint = signal (SIGINT, gdb_cntrl_c);
  prev_sigint = signal (SIGINT, gdb_cntrl_c);
 
 
  /* Wait for ready */
  /* Wait for ready */
  buf[0] = SDI_WAIT_FOR_READY;
  buf[0] = SDI_WAIT_FOR_READY;
  if (serial_write (sdi_desc, buf, 1) != 0)
  if (serial_write (sdi_desc, buf, 1) != 0)
    error (_("Remote connection closed"));
    error (_("Remote connection closed"));
 
 
  while (1)
  while (1)
    {
    {
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      if (c < 0)
      if (c < 0)
        error (_("Remote connection closed"));
        error (_("Remote connection closed"));
 
 
      if (c == '-')             /* error */
      if (c == '-')             /* error */
        {
        {
          status->kind = TARGET_WAITKIND_STOPPED;
          status->kind = TARGET_WAITKIND_STOPPED;
          status->value.sig = TARGET_SIGNAL_HUP;
          status->value.sig = TARGET_SIGNAL_HUP;
          return inferior_ptid;
          return inferior_ptid;
        }
        }
      else if (c == '+')        /* stopped */
      else if (c == '+')        /* stopped */
        break;
        break;
 
 
      if (interrupted)
      if (interrupted)
        ret = serial_write (sdi_desc, "!", 1);  /* packet to interrupt */
        ret = serial_write (sdi_desc, "!", 1);  /* packet to interrupt */
      else
      else
        ret = serial_write (sdi_desc, ".", 1);  /* packet to wait */
        ret = serial_write (sdi_desc, ".", 1);  /* packet to wait */
      if (ret != 0)
      if (ret != 0)
        error (_("Remote connection closed"));
        error (_("Remote connection closed"));
    }
    }
 
 
  status->kind = TARGET_WAITKIND_STOPPED;
  status->kind = TARGET_WAITKIND_STOPPED;
  if (interrupted)
  if (interrupted)
    status->value.sig = TARGET_SIGNAL_INT;
    status->value.sig = TARGET_SIGNAL_INT;
  else
  else
    status->value.sig = TARGET_SIGNAL_TRAP;
    status->value.sig = TARGET_SIGNAL_TRAP;
 
 
  interrupted = 0;
  interrupted = 0;
  signal (SIGINT, prev_sigint);
  signal (SIGINT, prev_sigint);
 
 
  check_mmu_status ();
  check_mmu_status ();
 
 
  /* Recover parallel bit. */
  /* Recover parallel bit. */
  if (last_pc_addr != 0xffffffff)
  if (last_pc_addr != 0xffffffff)
    {
    {
      buf[0] = SDI_WRITE_MEMORY;
      buf[0] = SDI_WRITE_MEMORY;
      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
        store_long_parameter (buf + 1, last_pc_addr);
        store_long_parameter (buf + 1, last_pc_addr);
      else
      else
        store_long_parameter (buf + 1, last_pc_addr - 1);
        store_long_parameter (buf + 1, last_pc_addr - 1);
      store_long_parameter (buf + 5, 1);
      store_long_parameter (buf + 5, 1);
      buf[9] = last_pc_addr_data[0];
      buf[9] = last_pc_addr_data[0];
      send_data (buf, 10);
      send_data (buf, 10);
      last_pc_addr = 0xffffffff;
      last_pc_addr = 0xffffffff;
    }
    }
 
 
  if (use_ib_breakpoints)
  if (use_ib_breakpoints)
    ib_breakpoints = max_ib_breakpoints;
    ib_breakpoints = max_ib_breakpoints;
  else
  else
    ib_breakpoints = 0;
    ib_breakpoints = 0;
 
 
  /* Set back pc by 2 if m32r is stopped with dbt. */
  /* Set back pc by 2 if m32r is stopped with dbt. */
  last_pc_addr = 0xffffffff;
  last_pc_addr = 0xffffffff;
  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BPC);
  send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BPC);
  pc_addr = recv_long_data () - 2;
  pc_addr = recv_long_data () - 2;
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
    {
    {
      if (pc_addr == bp_address[i])
      if (pc_addr == bp_address[i])
        {
        {
          send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BPC, pc_addr);
          send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BPC, pc_addr);
 
 
          /* If there is a parallel instruction with +2 offset at pc
          /* If there is a parallel instruction with +2 offset at pc
             address, we have to take care of it later. */
             address, we have to take care of it later. */
          if ((pc_addr & 0x2) != 0)
          if ((pc_addr & 0x2) != 0)
            {
            {
              if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
              if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
                {
                {
                  if ((bp_data[i][2] & 0x80) != 0)
                  if ((bp_data[i][2] & 0x80) != 0)
                    {
                    {
                      last_pc_addr = pc_addr;
                      last_pc_addr = pc_addr;
                      last_pc_addr_data[0] = bp_data[i][2];
                      last_pc_addr_data[0] = bp_data[i][2];
                      last_pc_addr_data[1] = bp_data[i][3];
                      last_pc_addr_data[1] = bp_data[i][3];
                    }
                    }
                }
                }
              else
              else
                {
                {
                  if ((bp_data[i][1] & 0x80) != 0)
                  if ((bp_data[i][1] & 0x80) != 0)
                    {
                    {
                      last_pc_addr = pc_addr;
                      last_pc_addr = pc_addr;
                      last_pc_addr_data[0] = bp_data[i][1];
                      last_pc_addr_data[0] = bp_data[i][1];
                      last_pc_addr_data[1] = bp_data[i][0];
                      last_pc_addr_data[1] = bp_data[i][0];
                    }
                    }
                }
                }
            }
            }
          break;
          break;
        }
        }
    }
    }
 
 
  /* Remove ib breakpoints. */
  /* Remove ib breakpoints. */
  for (i = 0; i < ib_breakpoints; i++)
  for (i = 0; i < ib_breakpoints; i++)
    {
    {
      if (bp_address[i] != 0xffffffff)
      if (bp_address[i] != 0xffffffff)
        send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
        send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8000 + 4 * i, 4,
                            0x00000000);
                            0x00000000);
    }
    }
  /* Remove dbt breakpoints. */
  /* Remove dbt breakpoints. */
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
  for (i = ib_breakpoints; i < MAX_BREAKPOINTS; i++)
    {
    {
      bp_addr = bp_address[i];
      bp_addr = bp_address[i];
      if (bp_addr != 0xffffffff)
      if (bp_addr != 0xffffffff)
        {
        {
          if (!mmu_on)
          if (!mmu_on)
            bp_addr &= 0x7fffffff;
            bp_addr &= 0x7fffffff;
          buf[0] = SDI_WRITE_MEMORY;
          buf[0] = SDI_WRITE_MEMORY;
          store_long_parameter (buf + 1, bp_addr & 0xfffffffc);
          store_long_parameter (buf + 1, bp_addr & 0xfffffffc);
          store_long_parameter (buf + 5, 4);
          store_long_parameter (buf + 5, 4);
          buf[9] = bp_data[i][0];
          buf[9] = bp_data[i][0];
          buf[10] = bp_data[i][1];
          buf[10] = bp_data[i][1];
          buf[11] = bp_data[i][2];
          buf[11] = bp_data[i][2];
          buf[12] = bp_data[i][3];
          buf[12] = bp_data[i][3];
          send_data (buf, 13);
          send_data (buf, 13);
        }
        }
    }
    }
 
 
  /* Remove access breaks. */
  /* Remove access breaks. */
  hit_watchpoint_addr = 0;
  hit_watchpoint_addr = 0;
  for (i = 0; i < max_access_breaks; i++)
  for (i = 0; i < max_access_breaks; i++)
    {
    {
      if (ab_address[i] != 0x00000000)
      if (ab_address[i] != 0x00000000)
        {
        {
          buf[0] = SDI_READ_MEMORY;
          buf[0] = SDI_READ_MEMORY;
          store_long_parameter (buf + 1, 0xffff8100 + 4 * i);
          store_long_parameter (buf + 1, 0xffff8100 + 4 * i);
          store_long_parameter (buf + 5, 4);
          store_long_parameter (buf + 5, 4);
          serial_write (sdi_desc, buf, 9);
          serial_write (sdi_desc, buf, 9);
          c = serial_readchar (sdi_desc, SDI_TIMEOUT);
          c = serial_readchar (sdi_desc, SDI_TIMEOUT);
          if (c != '-' && recv_data (buf, 4) != -1)
          if (c != '-' && recv_data (buf, 4) != -1)
            {
            {
              if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
              if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
                {
                {
                  if ((buf[3] & 0x1) == 0x1)
                  if ((buf[3] & 0x1) == 0x1)
                    hit_watchpoint_addr = ab_address[i];
                    hit_watchpoint_addr = ab_address[i];
                }
                }
              else
              else
                {
                {
                  if ((buf[0] & 0x1) == 0x1)
                  if ((buf[0] & 0x1) == 0x1)
                    hit_watchpoint_addr = ab_address[i];
                    hit_watchpoint_addr = ab_address[i];
                }
                }
            }
            }
 
 
          send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
          send_three_arg_cmd (SDI_WRITE_MEMORY, 0xffff8100 + 4 * i, 4,
                              0x00000000);
                              0x00000000);
        }
        }
    }
    }
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "pc => 0x%lx\n", pc_addr);
    fprintf_unfiltered (gdb_stdlog, "pc => 0x%lx\n", pc_addr);
 
 
  return inferior_ptid;
  return inferior_ptid;
}
}
 
 
/* Terminate the open connection to the remote debugger.
/* Terminate the open connection to the remote debugger.
   Use this when you want to detach and do something else
   Use this when you want to detach and do something else
   with your gdb.  */
   with your gdb.  */
static void
static void
m32r_detach (char *args, int from_tty)
m32r_detach (char *args, int from_tty)
{
{
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_detach(%d)\n", from_tty);
    fprintf_unfiltered (gdb_stdlog, "m32r_detach(%d)\n", from_tty);
 
 
  m32r_resume (inferior_ptid, 0, 0);
  m32r_resume (inferior_ptid, 0, 0);
 
 
  /* calls m32r_close to do the real work */
  /* calls m32r_close to do the real work */
  pop_target ();
  pop_target ();
  if (from_tty)
  if (from_tty)
    fprintf_unfiltered (gdb_stdlog, "Ending remote %s debugging\n",
    fprintf_unfiltered (gdb_stdlog, "Ending remote %s debugging\n",
                        target_shortname);
                        target_shortname);
}
}
 
 
/* Return the id of register number REGNO. */
/* Return the id of register number REGNO. */
 
 
static int
static int
get_reg_id (int regno)
get_reg_id (int regno)
{
{
  switch (regno)
  switch (regno)
    {
    {
    case 20:
    case 20:
      return SDI_REG_BBPC;
      return SDI_REG_BBPC;
    case 21:
    case 21:
      return SDI_REG_BPC;
      return SDI_REG_BPC;
    case 22:
    case 22:
      return SDI_REG_ACCL;
      return SDI_REG_ACCL;
    case 23:
    case 23:
      return SDI_REG_ACCH;
      return SDI_REG_ACCH;
    case 24:
    case 24:
      return SDI_REG_EVB;
      return SDI_REG_EVB;
    }
    }
 
 
  return regno;
  return regno;
}
}
 
 
/* Read the remote registers into the block REGS.  */
/* Read the remote registers into the block REGS.  */
 
 
static void m32r_fetch_register (struct regcache *, int);
static void m32r_fetch_register (struct regcache *, int);
 
 
static void
static void
m32r_fetch_registers (struct regcache *regcache)
m32r_fetch_registers (struct regcache *regcache)
{
{
  int regno;
  int regno;
 
 
  for (regno = 0;
  for (regno = 0;
       regno < gdbarch_num_regs (get_regcache_arch (regcache));
       regno < gdbarch_num_regs (get_regcache_arch (regcache));
       regno++)
       regno++)
    m32r_fetch_register (regcache, regno);
    m32r_fetch_register (regcache, regno);
}
}
 
 
/* Fetch register REGNO, or all registers if REGNO is -1.
/* Fetch register REGNO, or all registers if REGNO is -1.
   Returns errno value.  */
   Returns errno value.  */
static void
static void
m32r_fetch_register (struct regcache *regcache, int regno)
m32r_fetch_register (struct regcache *regcache, int regno)
{
{
  unsigned long val, val2, regid;
  unsigned long val, val2, regid;
 
 
  if (regno == -1)
  if (regno == -1)
    m32r_fetch_registers (regcache);
    m32r_fetch_registers (regcache);
  else
  else
    {
    {
      char buffer[MAX_REGISTER_SIZE];
      char buffer[MAX_REGISTER_SIZE];
 
 
      regid = get_reg_id (regno);
      regid = get_reg_id (regno);
      send_one_arg_cmd (SDI_READ_CPU_REG, regid);
      send_one_arg_cmd (SDI_READ_CPU_REG, regid);
      val = recv_long_data ();
      val = recv_long_data ();
 
 
      if (regid == SDI_REG_PSW)
      if (regid == SDI_REG_PSW)
        {
        {
          send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
          send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
          val2 = recv_long_data ();
          val2 = recv_long_data ();
          val = ((0x00cf & val2) << 8) | ((0xcf00 & val) >> 8);
          val = ((0x00cf & val2) << 8) | ((0xcf00 & val) >> 8);
        }
        }
 
 
      if (remote_debug)
      if (remote_debug)
        fprintf_unfiltered (gdb_stdlog, "m32r_fetch_register(%d,0x%08lx)\n",
        fprintf_unfiltered (gdb_stdlog, "m32r_fetch_register(%d,0x%08lx)\n",
                            regno, val);
                            regno, val);
 
 
      /* We got the number the register holds, but gdb expects to see a
      /* We got the number the register holds, but gdb expects to see a
         value in the target byte ordering.  */
         value in the target byte ordering.  */
      store_unsigned_integer (buffer, 4, val);
      store_unsigned_integer (buffer, 4, val);
      regcache_raw_supply (regcache, regno, buffer);
      regcache_raw_supply (regcache, regno, buffer);
    }
    }
  return;
  return;
}
}
 
 
/* Store the remote registers from the contents of the block REGS.  */
/* Store the remote registers from the contents of the block REGS.  */
 
 
static void m32r_store_register (struct regcache *, int);
static void m32r_store_register (struct regcache *, int);
 
 
static void
static void
m32r_store_registers (struct regcache *regcache)
m32r_store_registers (struct regcache *regcache)
{
{
  int regno;
  int regno;
 
 
  for (regno = 0;
  for (regno = 0;
       regno < gdbarch_num_regs (get_regcache_arch (regcache));
       regno < gdbarch_num_regs (get_regcache_arch (regcache));
       regno++)
       regno++)
    m32r_store_register (regcache, regno);
    m32r_store_register (regcache, regno);
 
 
  registers_changed ();
  registers_changed ();
}
}
 
 
/* Store register REGNO, or all if REGNO == 0.
/* Store register REGNO, or all if REGNO == 0.
   Return errno value.  */
   Return errno value.  */
static void
static void
m32r_store_register (struct regcache *regcache, int regno)
m32r_store_register (struct regcache *regcache, int regno)
{
{
  int regid;
  int regid;
  ULONGEST regval, tmp;
  ULONGEST regval, tmp;
 
 
  if (regno == -1)
  if (regno == -1)
    m32r_store_registers (regcache);
    m32r_store_registers (regcache);
  else
  else
    {
    {
      regcache_cooked_read_unsigned (regcache, regno, &regval);
      regcache_cooked_read_unsigned (regcache, regno, &regval);
      regid = get_reg_id (regno);
      regid = get_reg_id (regno);
 
 
      if (regid == SDI_REG_PSW)
      if (regid == SDI_REG_PSW)
        {
        {
          unsigned long psw, bbpsw;
          unsigned long psw, bbpsw;
 
 
          send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_PSW);
          send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_PSW);
          psw = recv_long_data ();
          psw = recv_long_data ();
 
 
          send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
          send_one_arg_cmd (SDI_READ_CPU_REG, SDI_REG_BBPSW);
          bbpsw = recv_long_data ();
          bbpsw = recv_long_data ();
 
 
          tmp = (0x00cf & psw) | ((0x00cf & regval) << 8);
          tmp = (0x00cf & psw) | ((0x00cf & regval) << 8);
          send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PSW, tmp);
          send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_PSW, tmp);
 
 
          tmp = (0x0030 & bbpsw) | ((0xcf00 & regval) >> 8);
          tmp = (0x0030 & bbpsw) | ((0xcf00 & regval) >> 8);
          send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BBPSW, tmp);
          send_two_arg_cmd (SDI_WRITE_CPU_REG, SDI_REG_BBPSW, tmp);
        }
        }
      else
      else
        {
        {
          send_two_arg_cmd (SDI_WRITE_CPU_REG, regid, regval);
          send_two_arg_cmd (SDI_WRITE_CPU_REG, regid, regval);
        }
        }
 
 
      if (remote_debug)
      if (remote_debug)
        fprintf_unfiltered (gdb_stdlog, "m32r_store_register(%d,0x%08lu)\n",
        fprintf_unfiltered (gdb_stdlog, "m32r_store_register(%d,0x%08lu)\n",
                            regno, (unsigned long) regval);
                            regno, (unsigned long) regval);
    }
    }
}
}
 
 
/* Get ready to modify the registers array.  On machines which store
/* Get ready to modify the registers array.  On machines which store
   individual registers, this doesn't need to do anything.  On machines
   individual registers, this doesn't need to do anything.  On machines
   which store all the registers in one fell swoop, this makes sure
   which store all the registers in one fell swoop, this makes sure
   that registers contains all the registers from the program being
   that registers contains all the registers from the program being
   debugged.  */
   debugged.  */
 
 
static void
static void
m32r_prepare_to_store (struct regcache *regcache)
m32r_prepare_to_store (struct regcache *regcache)
{
{
  /* Do nothing, since we can store individual regs */
  /* Do nothing, since we can store individual regs */
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_prepare_to_store()\n");
    fprintf_unfiltered (gdb_stdlog, "m32r_prepare_to_store()\n");
}
}
 
 
static void
static void
m32r_files_info (struct target_ops *target)
m32r_files_info (struct target_ops *target)
{
{
  char *file = "nothing";
  char *file = "nothing";
 
 
  if (exec_bfd)
  if (exec_bfd)
    {
    {
      file = bfd_get_filename (exec_bfd);
      file = bfd_get_filename (exec_bfd);
      printf_filtered ("\tAttached to %s running program %s\n",
      printf_filtered ("\tAttached to %s running program %s\n",
                       chip_name, file);
                       chip_name, file);
    }
    }
}
}
 
 
/* Read/Write memory.  */
/* Read/Write memory.  */
static int
static int
m32r_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
m32r_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
                  int write,
                  int write,
                  struct mem_attrib *attrib, struct target_ops *target)
                  struct mem_attrib *attrib, struct target_ops *target)
{
{
  unsigned long taddr;
  unsigned long taddr;
  unsigned char buf[0x2000];
  unsigned char buf[0x2000];
  int ret, c;
  int ret, c;
 
 
  taddr = memaddr;
  taddr = memaddr;
 
 
  if (!mmu_on)
  if (!mmu_on)
    {
    {
      if ((taddr & 0xa0000000) == 0x80000000)
      if ((taddr & 0xa0000000) == 0x80000000)
        taddr &= 0x7fffffff;
        taddr &= 0x7fffffff;
    }
    }
 
 
  if (remote_debug)
  if (remote_debug)
    {
    {
      if (write)
      if (write)
        fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%s,%d,write)\n",
        fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%s,%d,write)\n",
                            paddr (memaddr), len);
                            paddr (memaddr), len);
      else
      else
        fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%s,%d,read)\n",
        fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory(%s,%d,read)\n",
                            paddr (memaddr), len);
                            paddr (memaddr), len);
    }
    }
 
 
  if (write)
  if (write)
    {
    {
      buf[0] = SDI_WRITE_MEMORY;
      buf[0] = SDI_WRITE_MEMORY;
      store_long_parameter (buf + 1, taddr);
      store_long_parameter (buf + 1, taddr);
      store_long_parameter (buf + 5, len);
      store_long_parameter (buf + 5, len);
      if (len < 0x1000)
      if (len < 0x1000)
        {
        {
          memcpy (buf + 9, myaddr, len);
          memcpy (buf + 9, myaddr, len);
          ret = send_data (buf, len + 9) - 9;
          ret = send_data (buf, len + 9) - 9;
        }
        }
      else
      else
        {
        {
          if (serial_write (sdi_desc, buf, 9) != 0)
          if (serial_write (sdi_desc, buf, 9) != 0)
            {
            {
              if (remote_debug)
              if (remote_debug)
                fprintf_unfiltered (gdb_stdlog,
                fprintf_unfiltered (gdb_stdlog,
                                    "m32r_xfer_memory() failed\n");
                                    "m32r_xfer_memory() failed\n");
              return 0;
              return 0;
            }
            }
          ret = send_data (myaddr, len);
          ret = send_data (myaddr, len);
        }
        }
    }
    }
  else
  else
    {
    {
      buf[0] = SDI_READ_MEMORY;
      buf[0] = SDI_READ_MEMORY;
      store_long_parameter (buf + 1, taddr);
      store_long_parameter (buf + 1, taddr);
      store_long_parameter (buf + 5, len);
      store_long_parameter (buf + 5, len);
      if (serial_write (sdi_desc, buf, 9) != 0)
      if (serial_write (sdi_desc, buf, 9) != 0)
        {
        {
          if (remote_debug)
          if (remote_debug)
            fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n");
            fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n");
          return 0;
          return 0;
        }
        }
 
 
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      if (c < 0 || c == '-')
      if (c < 0 || c == '-')
        {
        {
          if (remote_debug)
          if (remote_debug)
            fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n");
            fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() failed\n");
          return 0;
          return 0;
        }
        }
 
 
      ret = recv_data (myaddr, len);
      ret = recv_data (myaddr, len);
    }
    }
 
 
  if (ret <= 0)
  if (ret <= 0)
    {
    {
      if (remote_debug)
      if (remote_debug)
        fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() fails\n");
        fprintf_unfiltered (gdb_stdlog, "m32r_xfer_memory() fails\n");
      return 0;
      return 0;
    }
    }
 
 
  return ret;
  return ret;
}
}
 
 
static void
static void
m32r_kill (void)
m32r_kill (void)
{
{
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_kill()\n");
    fprintf_unfiltered (gdb_stdlog, "m32r_kill()\n");
 
 
  inferior_ptid = null_ptid;
  inferior_ptid = null_ptid;
 
 
  return;
  return;
}
}
 
 
/* Clean up when a program exits.
/* Clean up when a program exits.
 
 
   The program actually lives on in the remote processor's RAM, and may be
   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
   run again without a download.  Don't leave it full of breakpoint
   instructions.  */
   instructions.  */
 
 
static void
static void
m32r_mourn_inferior (void)
m32r_mourn_inferior (void)
{
{
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_mourn_inferior()\n");
    fprintf_unfiltered (gdb_stdlog, "m32r_mourn_inferior()\n");
 
 
  remove_breakpoints ();
  remove_breakpoints ();
  generic_mourn_inferior ();
  generic_mourn_inferior ();
}
}
 
 
static int
static int
m32r_insert_breakpoint (struct bp_target_info *bp_tgt)
m32r_insert_breakpoint (struct bp_target_info *bp_tgt)
{
{
  CORE_ADDR addr = bp_tgt->placed_address;
  CORE_ADDR addr = bp_tgt->placed_address;
  int ib_breakpoints;
  int ib_breakpoints;
  unsigned char buf[13];
  unsigned char buf[13];
  int i, c;
  int i, c;
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%s,...)\n",
    fprintf_unfiltered (gdb_stdlog, "m32r_insert_breakpoint(%s,...)\n",
                        paddr (addr));
                        paddr (addr));
 
 
  if (use_ib_breakpoints)
  if (use_ib_breakpoints)
    ib_breakpoints = max_ib_breakpoints;
    ib_breakpoints = max_ib_breakpoints;
  else
  else
    ib_breakpoints = 0;
    ib_breakpoints = 0;
 
 
  for (i = 0; i < MAX_BREAKPOINTS; i++)
  for (i = 0; i < MAX_BREAKPOINTS; i++)
    {
    {
      if (bp_address[i] == 0xffffffff)
      if (bp_address[i] == 0xffffffff)
        {
        {
          bp_address[i] = addr;
          bp_address[i] = addr;
          if (i >= ib_breakpoints)
          if (i >= ib_breakpoints)
            {
            {
              buf[0] = SDI_READ_MEMORY;
              buf[0] = SDI_READ_MEMORY;
              if (mmu_on)
              if (mmu_on)
                store_long_parameter (buf + 1, addr & 0xfffffffc);
                store_long_parameter (buf + 1, addr & 0xfffffffc);
              else
              else
                store_long_parameter (buf + 1, addr & 0x7ffffffc);
                store_long_parameter (buf + 1, addr & 0x7ffffffc);
              store_long_parameter (buf + 5, 4);
              store_long_parameter (buf + 5, 4);
              serial_write (sdi_desc, buf, 9);
              serial_write (sdi_desc, buf, 9);
              c = serial_readchar (sdi_desc, SDI_TIMEOUT);
              c = serial_readchar (sdi_desc, SDI_TIMEOUT);
              if (c != '-')
              if (c != '-')
                recv_data (bp_data[i], 4);
                recv_data (bp_data[i], 4);
            }
            }
          return 0;
          return 0;
        }
        }
    }
    }
 
 
  error (_("Too many breakpoints"));
  error (_("Too many breakpoints"));
  return 1;
  return 1;
}
}
 
 
static int
static int
m32r_remove_breakpoint (struct bp_target_info *bp_tgt)
m32r_remove_breakpoint (struct bp_target_info *bp_tgt)
{
{
  CORE_ADDR addr = bp_tgt->placed_address;
  CORE_ADDR addr = bp_tgt->placed_address;
  int i;
  int i;
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%s)\n",
    fprintf_unfiltered (gdb_stdlog, "m32r_remove_breakpoint(%s)\n",
                        paddr (addr));
                        paddr (addr));
 
 
  for (i = 0; i < MAX_BREAKPOINTS; i++)
  for (i = 0; i < MAX_BREAKPOINTS; i++)
    {
    {
      if (bp_address[i] == addr)
      if (bp_address[i] == addr)
        {
        {
          bp_address[i] = 0xffffffff;
          bp_address[i] = 0xffffffff;
          break;
          break;
        }
        }
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
static void
static void
m32r_load (char *args, int from_tty)
m32r_load (char *args, int from_tty)
{
{
  struct cleanup *old_chain;
  struct cleanup *old_chain;
  asection *section;
  asection *section;
  bfd *pbfd;
  bfd *pbfd;
  bfd_vma entry;
  bfd_vma entry;
  char *filename;
  char *filename;
  int quiet;
  int quiet;
  int nostart;
  int nostart;
  struct timeval start_time, end_time;
  struct timeval start_time, end_time;
  unsigned long data_count;     /* Number of bytes transferred to memory */
  unsigned long data_count;     /* Number of bytes transferred to memory */
  int ret;
  int ret;
  static RETSIGTYPE (*prev_sigint) ();
  static RETSIGTYPE (*prev_sigint) ();
 
 
  /* for direct tcp connections, we can do a fast binary download */
  /* for direct tcp connections, we can do a fast binary download */
  quiet = 0;
  quiet = 0;
  nostart = 0;
  nostart = 0;
  filename = NULL;
  filename = NULL;
 
 
  while (*args != '\000')
  while (*args != '\000')
    {
    {
      char *arg;
      char *arg;
 
 
      while (isspace (*args))
      while (isspace (*args))
        args++;
        args++;
 
 
      arg = args;
      arg = args;
 
 
      while ((*args != '\000') && !isspace (*args))
      while ((*args != '\000') && !isspace (*args))
        args++;
        args++;
 
 
      if (*args != '\000')
      if (*args != '\000')
        *args++ = '\000';
        *args++ = '\000';
 
 
      if (*arg != '-')
      if (*arg != '-')
        filename = arg;
        filename = arg;
      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
        quiet = 1;
        quiet = 1;
      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
        nostart = 1;
        nostart = 1;
      else
      else
        error (_("Unknown option `%s'"), arg);
        error (_("Unknown option `%s'"), arg);
    }
    }
 
 
  if (!filename)
  if (!filename)
    filename = get_exec_file (1);
    filename = get_exec_file (1);
 
 
  pbfd = bfd_openr (filename, gnutarget);
  pbfd = bfd_openr (filename, gnutarget);
  if (pbfd == NULL)
  if (pbfd == NULL)
    {
    {
      perror_with_name (filename);
      perror_with_name (filename);
      return;
      return;
    }
    }
  old_chain = make_cleanup_bfd_close (pbfd);
  old_chain = make_cleanup_bfd_close (pbfd);
 
 
  if (!bfd_check_format (pbfd, bfd_object))
  if (!bfd_check_format (pbfd, bfd_object))
    error (_("\"%s\" is not an object file: %s"), filename,
    error (_("\"%s\" is not an object file: %s"), filename,
           bfd_errmsg (bfd_get_error ()));
           bfd_errmsg (bfd_get_error ()));
 
 
  gettimeofday (&start_time, NULL);
  gettimeofday (&start_time, NULL);
  data_count = 0;
  data_count = 0;
 
 
  interrupted = 0;
  interrupted = 0;
  prev_sigint = signal (SIGINT, gdb_cntrl_c);
  prev_sigint = signal (SIGINT, gdb_cntrl_c);
 
 
  for (section = pbfd->sections; section; section = section->next)
  for (section = pbfd->sections; section; section = section->next)
    {
    {
      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
        {
        {
          bfd_vma section_address;
          bfd_vma section_address;
          bfd_size_type section_size;
          bfd_size_type section_size;
          file_ptr fptr;
          file_ptr fptr;
          int n;
          int n;
 
 
          section_address = bfd_section_lma (pbfd, section);
          section_address = bfd_section_lma (pbfd, section);
          section_size = bfd_get_section_size (section);
          section_size = bfd_get_section_size (section);
 
 
          if (!mmu_on)
          if (!mmu_on)
            {
            {
              if ((section_address & 0xa0000000) == 0x80000000)
              if ((section_address & 0xa0000000) == 0x80000000)
                section_address &= 0x7fffffff;
                section_address &= 0x7fffffff;
            }
            }
 
 
          if (!quiet)
          if (!quiet)
            printf_filtered ("[Loading section %s at 0x%lx (%d bytes)]\n",
            printf_filtered ("[Loading section %s at 0x%lx (%d bytes)]\n",
                             bfd_get_section_name (pbfd, section),
                             bfd_get_section_name (pbfd, section),
                             (unsigned long) section_address,
                             (unsigned long) section_address,
                             (int) section_size);
                             (int) section_size);
 
 
          fptr = 0;
          fptr = 0;
 
 
          data_count += section_size;
          data_count += section_size;
 
 
          n = 0;
          n = 0;
          while (section_size > 0)
          while (section_size > 0)
            {
            {
              char unsigned buf[0x1000 + 9];
              char unsigned buf[0x1000 + 9];
              int count;
              int count;
 
 
              count = min (section_size, 0x1000);
              count = min (section_size, 0x1000);
 
 
              buf[0] = SDI_WRITE_MEMORY;
              buf[0] = SDI_WRITE_MEMORY;
              store_long_parameter (buf + 1, section_address);
              store_long_parameter (buf + 1, section_address);
              store_long_parameter (buf + 5, count);
              store_long_parameter (buf + 5, count);
 
 
              bfd_get_section_contents (pbfd, section, buf + 9, fptr, count);
              bfd_get_section_contents (pbfd, section, buf + 9, fptr, count);
              if (send_data (buf, count + 9) <= 0)
              if (send_data (buf, count + 9) <= 0)
                error (_("Error while downloading %s section."),
                error (_("Error while downloading %s section."),
                       bfd_get_section_name (pbfd, section));
                       bfd_get_section_name (pbfd, section));
 
 
              if (!quiet)
              if (!quiet)
                {
                {
                  printf_unfiltered (".");
                  printf_unfiltered (".");
                  if (n++ > 60)
                  if (n++ > 60)
                    {
                    {
                      printf_unfiltered ("\n");
                      printf_unfiltered ("\n");
                      n = 0;
                      n = 0;
                    }
                    }
                  gdb_flush (gdb_stdout);
                  gdb_flush (gdb_stdout);
                }
                }
 
 
              section_address += count;
              section_address += count;
              fptr += count;
              fptr += count;
              section_size -= count;
              section_size -= count;
 
 
              if (interrupted)
              if (interrupted)
                break;
                break;
            }
            }
 
 
          if (!quiet && !interrupted)
          if (!quiet && !interrupted)
            {
            {
              printf_unfiltered ("done.\n");
              printf_unfiltered ("done.\n");
              gdb_flush (gdb_stdout);
              gdb_flush (gdb_stdout);
            }
            }
        }
        }
 
 
      if (interrupted)
      if (interrupted)
        {
        {
          printf_unfiltered ("Interrupted.\n");
          printf_unfiltered ("Interrupted.\n");
          break;
          break;
        }
        }
    }
    }
 
 
  interrupted = 0;
  interrupted = 0;
  signal (SIGINT, prev_sigint);
  signal (SIGINT, prev_sigint);
 
 
  gettimeofday (&end_time, NULL);
  gettimeofday (&end_time, NULL);
 
 
  /* Make the PC point at the start address */
  /* Make the PC point at the start address */
  if (exec_bfd)
  if (exec_bfd)
    write_pc (bfd_get_start_address (exec_bfd));
    write_pc (bfd_get_start_address (exec_bfd));
 
 
  inferior_ptid = null_ptid;    /* No process now */
  inferior_ptid = null_ptid;    /* No process now */
 
 
  /* This is necessary because many things were based on the PC at the time
  /* 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
     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
     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,
     might be to call normal_stop, except that the stack may not be valid,
     and things would get horribly confused... */
     and things would get horribly confused... */
 
 
  clear_symtab_users ();
  clear_symtab_users ();
 
 
  if (!nostart)
  if (!nostart)
    {
    {
      entry = bfd_get_start_address (pbfd);
      entry = bfd_get_start_address (pbfd);
 
 
      if (!quiet)
      if (!quiet)
        printf_unfiltered ("[Starting %s at 0x%lx]\n", filename,
        printf_unfiltered ("[Starting %s at 0x%lx]\n", filename,
                           (unsigned long) entry);
                           (unsigned long) entry);
    }
    }
 
 
  print_transfer_performance (gdb_stdout, data_count, 0, &start_time,
  print_transfer_performance (gdb_stdout, data_count, 0, &start_time,
                              &end_time);
                              &end_time);
 
 
  do_cleanups (old_chain);
  do_cleanups (old_chain);
}
}
 
 
static void
static void
m32r_stop (void)
m32r_stop (void)
{
{
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_stop()\n");
    fprintf_unfiltered (gdb_stdlog, "m32r_stop()\n");
 
 
  send_cmd (SDI_STOP_CPU);
  send_cmd (SDI_STOP_CPU);
 
 
  return;
  return;
}
}
 
 
 
 
/* Tell whether this target can support a hardware breakpoint.  CNT
/* Tell whether this target can support a hardware breakpoint.  CNT
   is the number of hardware breakpoints already installed.  This
   is the number of hardware breakpoints already installed.  This
   implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro.  */
   implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro.  */
 
 
int
int
m32r_can_use_hw_watchpoint (int type, int cnt, int othertype)
m32r_can_use_hw_watchpoint (int type, int cnt, int othertype)
{
{
  return sdi_desc != NULL && cnt < max_access_breaks;
  return sdi_desc != NULL && cnt < max_access_breaks;
}
}
 
 
/* Set a data watchpoint.  ADDR and LEN should be obvious.  TYPE is 0
/* 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
   for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
   watchpoint. */
   watchpoint. */
 
 
int
int
m32r_insert_watchpoint (CORE_ADDR addr, int len, int type)
m32r_insert_watchpoint (CORE_ADDR addr, int len, int type)
{
{
  int i;
  int i;
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_insert_watchpoint(%s,%d,%d)\n",
    fprintf_unfiltered (gdb_stdlog, "m32r_insert_watchpoint(%s,%d,%d)\n",
                        paddr (addr), len, type);
                        paddr (addr), len, type);
 
 
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
    {
    {
      if (ab_address[i] == 0x00000000)
      if (ab_address[i] == 0x00000000)
        {
        {
          ab_address[i] = addr;
          ab_address[i] = addr;
          ab_size[i] = len;
          ab_size[i] = len;
          ab_type[i] = type;
          ab_type[i] = type;
          return 0;
          return 0;
        }
        }
    }
    }
 
 
  error (_("Too many watchpoints"));
  error (_("Too many watchpoints"));
  return 1;
  return 1;
}
}
 
 
int
int
m32r_remove_watchpoint (CORE_ADDR addr, int len, int type)
m32r_remove_watchpoint (CORE_ADDR addr, int len, int type)
{
{
  int i;
  int i;
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_remove_watchpoint(%s,%d,%d)\n",
    fprintf_unfiltered (gdb_stdlog, "m32r_remove_watchpoint(%s,%d,%d)\n",
                        paddr (addr), len, type);
                        paddr (addr), len, type);
 
 
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
    {
    {
      if (ab_address[i] == addr)
      if (ab_address[i] == addr)
        {
        {
          ab_address[i] = 0x00000000;
          ab_address[i] = 0x00000000;
          break;
          break;
        }
        }
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
int
int
m32r_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
m32r_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p)
{
{
  int rc = 0;
  int rc = 0;
  if (hit_watchpoint_addr != 0x00000000)
  if (hit_watchpoint_addr != 0x00000000)
    {
    {
      *addr_p = hit_watchpoint_addr;
      *addr_p = hit_watchpoint_addr;
      rc = 1;
      rc = 1;
    }
    }
  return rc;
  return rc;
}
}
 
 
int
int
m32r_stopped_by_watchpoint (void)
m32r_stopped_by_watchpoint (void)
{
{
  CORE_ADDR addr;
  CORE_ADDR addr;
  return m32r_stopped_data_address (&current_target, &addr);
  return m32r_stopped_data_address (&current_target, &addr);
}
}
 
 
 
 
static void
static void
sdireset_command (char *args, int from_tty)
sdireset_command (char *args, int from_tty)
{
{
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n");
    fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n");
 
 
  send_cmd (SDI_OPEN);
  send_cmd (SDI_OPEN);
 
 
  inferior_ptid = null_ptid;
  inferior_ptid = null_ptid;
}
}
 
 
 
 
static void
static void
sdistatus_command (char *args, int from_tty)
sdistatus_command (char *args, int from_tty)
{
{
  unsigned char buf[4096];
  unsigned char buf[4096];
  int i, c;
  int i, c;
 
 
  if (remote_debug)
  if (remote_debug)
    fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n");
    fprintf_unfiltered (gdb_stdlog, "m32r_sdireset()\n");
 
 
  if (!sdi_desc)
  if (!sdi_desc)
    return;
    return;
 
 
  send_cmd (SDI_STATUS);
  send_cmd (SDI_STATUS);
  for (i = 0; i < 4096; i++)
  for (i = 0; i < 4096; i++)
    {
    {
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      c = serial_readchar (sdi_desc, SDI_TIMEOUT);
      if (c < 0)
      if (c < 0)
        return;
        return;
      buf[i] = c;
      buf[i] = c;
      if (c == 0)
      if (c == 0)
        break;
        break;
    }
    }
 
 
  printf_filtered ("%s", buf);
  printf_filtered ("%s", buf);
}
}
 
 
 
 
static void
static void
debug_chaos_command (char *args, int from_tty)
debug_chaos_command (char *args, int from_tty)
{
{
  unsigned char buf[3];
  unsigned char buf[3];
 
 
  buf[0] = SDI_SET_ATTR;
  buf[0] = SDI_SET_ATTR;
  buf[1] = SDI_ATTR_CACHE;
  buf[1] = SDI_ATTR_CACHE;
  buf[2] = SDI_CACHE_TYPE_CHAOS;
  buf[2] = SDI_CACHE_TYPE_CHAOS;
  send_data (buf, 3);
  send_data (buf, 3);
}
}
 
 
 
 
static void
static void
use_debug_dma_command (char *args, int from_tty)
use_debug_dma_command (char *args, int from_tty)
{
{
  unsigned char buf[3];
  unsigned char buf[3];
 
 
  buf[0] = SDI_SET_ATTR;
  buf[0] = SDI_SET_ATTR;
  buf[1] = SDI_ATTR_MEM_ACCESS;
  buf[1] = SDI_ATTR_MEM_ACCESS;
  buf[2] = SDI_MEM_ACCESS_DEBUG_DMA;
  buf[2] = SDI_MEM_ACCESS_DEBUG_DMA;
  send_data (buf, 3);
  send_data (buf, 3);
}
}
 
 
static void
static void
use_mon_code_command (char *args, int from_tty)
use_mon_code_command (char *args, int from_tty)
{
{
  unsigned char buf[3];
  unsigned char buf[3];
 
 
  buf[0] = SDI_SET_ATTR;
  buf[0] = SDI_SET_ATTR;
  buf[1] = SDI_ATTR_MEM_ACCESS;
  buf[1] = SDI_ATTR_MEM_ACCESS;
  buf[2] = SDI_MEM_ACCESS_MON_CODE;
  buf[2] = SDI_MEM_ACCESS_MON_CODE;
  send_data (buf, 3);
  send_data (buf, 3);
}
}
 
 
 
 
static void
static void
use_ib_breakpoints_command (char *args, int from_tty)
use_ib_breakpoints_command (char *args, int from_tty)
{
{
  use_ib_breakpoints = 1;
  use_ib_breakpoints = 1;
}
}
 
 
static void
static void
use_dbt_breakpoints_command (char *args, int from_tty)
use_dbt_breakpoints_command (char *args, int from_tty)
{
{
  use_ib_breakpoints = 0;
  use_ib_breakpoints = 0;
}
}
 
 
 
 
/* Define the target subroutine names */
/* Define the target subroutine names */
 
 
struct target_ops m32r_ops;
struct target_ops m32r_ops;
 
 
static void
static void
init_m32r_ops (void)
init_m32r_ops (void)
{
{
  m32r_ops.to_shortname = "m32rsdi";
  m32r_ops.to_shortname = "m32rsdi";
  m32r_ops.to_longname = "Remote M32R debugging over SDI interface";
  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_doc = "Use an M32R board using SDI debugging protocol.";
  m32r_ops.to_open = m32r_open;
  m32r_ops.to_open = m32r_open;
  m32r_ops.to_close = m32r_close;
  m32r_ops.to_close = m32r_close;
  m32r_ops.to_detach = m32r_detach;
  m32r_ops.to_detach = m32r_detach;
  m32r_ops.to_resume = m32r_resume;
  m32r_ops.to_resume = m32r_resume;
  m32r_ops.to_wait = m32r_wait;
  m32r_ops.to_wait = m32r_wait;
  m32r_ops.to_fetch_registers = m32r_fetch_register;
  m32r_ops.to_fetch_registers = m32r_fetch_register;
  m32r_ops.to_store_registers = m32r_store_register;
  m32r_ops.to_store_registers = m32r_store_register;
  m32r_ops.to_prepare_to_store = m32r_prepare_to_store;
  m32r_ops.to_prepare_to_store = m32r_prepare_to_store;
  m32r_ops.deprecated_xfer_memory = m32r_xfer_memory;
  m32r_ops.deprecated_xfer_memory = m32r_xfer_memory;
  m32r_ops.to_files_info = m32r_files_info;
  m32r_ops.to_files_info = m32r_files_info;
  m32r_ops.to_insert_breakpoint = m32r_insert_breakpoint;
  m32r_ops.to_insert_breakpoint = m32r_insert_breakpoint;
  m32r_ops.to_remove_breakpoint = m32r_remove_breakpoint;
  m32r_ops.to_remove_breakpoint = m32r_remove_breakpoint;
  m32r_ops.to_can_use_hw_breakpoint = m32r_can_use_hw_watchpoint;
  m32r_ops.to_can_use_hw_breakpoint = m32r_can_use_hw_watchpoint;
  m32r_ops.to_insert_watchpoint = m32r_insert_watchpoint;
  m32r_ops.to_insert_watchpoint = m32r_insert_watchpoint;
  m32r_ops.to_remove_watchpoint = m32r_remove_watchpoint;
  m32r_ops.to_remove_watchpoint = m32r_remove_watchpoint;
  m32r_ops.to_stopped_by_watchpoint = m32r_stopped_by_watchpoint;
  m32r_ops.to_stopped_by_watchpoint = m32r_stopped_by_watchpoint;
  m32r_ops.to_stopped_data_address = m32r_stopped_data_address;
  m32r_ops.to_stopped_data_address = m32r_stopped_data_address;
  m32r_ops.to_kill = m32r_kill;
  m32r_ops.to_kill = m32r_kill;
  m32r_ops.to_load = m32r_load;
  m32r_ops.to_load = m32r_load;
  m32r_ops.to_create_inferior = m32r_create_inferior;
  m32r_ops.to_create_inferior = m32r_create_inferior;
  m32r_ops.to_mourn_inferior = m32r_mourn_inferior;
  m32r_ops.to_mourn_inferior = m32r_mourn_inferior;
  m32r_ops.to_stop = m32r_stop;
  m32r_ops.to_stop = m32r_stop;
  m32r_ops.to_log_command = serial_log_command;
  m32r_ops.to_log_command = serial_log_command;
  m32r_ops.to_stratum = process_stratum;
  m32r_ops.to_stratum = process_stratum;
  m32r_ops.to_has_all_memory = 1;
  m32r_ops.to_has_all_memory = 1;
  m32r_ops.to_has_memory = 1;
  m32r_ops.to_has_memory = 1;
  m32r_ops.to_has_stack = 1;
  m32r_ops.to_has_stack = 1;
  m32r_ops.to_has_registers = 1;
  m32r_ops.to_has_registers = 1;
  m32r_ops.to_has_execution = 1;
  m32r_ops.to_has_execution = 1;
  m32r_ops.to_magic = OPS_MAGIC;
  m32r_ops.to_magic = OPS_MAGIC;
};
};
 
 
 
 
extern initialize_file_ftype _initialize_remote_m32r;
extern initialize_file_ftype _initialize_remote_m32r;
 
 
void
void
_initialize_remote_m32r (void)
_initialize_remote_m32r (void)
{
{
  int i;
  int i;
 
 
  init_m32r_ops ();
  init_m32r_ops ();
 
 
  /* Initialize breakpoints. */
  /* Initialize breakpoints. */
  for (i = 0; i < MAX_BREAKPOINTS; i++)
  for (i = 0; i < MAX_BREAKPOINTS; i++)
    bp_address[i] = 0xffffffff;
    bp_address[i] = 0xffffffff;
 
 
  /* Initialize access breaks. */
  /* Initialize access breaks. */
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
  for (i = 0; i < MAX_ACCESS_BREAKS; i++)
    ab_address[i] = 0x00000000;
    ab_address[i] = 0x00000000;
 
 
  add_target (&m32r_ops);
  add_target (&m32r_ops);
 
 
  add_com ("sdireset", class_obscure, sdireset_command,
  add_com ("sdireset", class_obscure, sdireset_command,
           _("Reset SDI connection."));
           _("Reset SDI connection."));
 
 
  add_com ("sdistatus", class_obscure, sdistatus_command,
  add_com ("sdistatus", class_obscure, sdistatus_command,
           _("Show status of SDI connection."));
           _("Show status of SDI connection."));
 
 
  add_com ("debug_chaos", class_obscure, debug_chaos_command,
  add_com ("debug_chaos", class_obscure, debug_chaos_command,
           _("Debug M32R/Chaos."));
           _("Debug M32R/Chaos."));
 
 
  add_com ("use_debug_dma", class_obscure, use_debug_dma_command,
  add_com ("use_debug_dma", class_obscure, use_debug_dma_command,
           _("Use debug DMA mem access."));
           _("Use debug DMA mem access."));
  add_com ("use_mon_code", class_obscure, use_mon_code_command,
  add_com ("use_mon_code", class_obscure, use_mon_code_command,
           _("Use mon code mem access."));
           _("Use mon code mem access."));
 
 
  add_com ("use_ib_break", class_obscure, use_ib_breakpoints_command,
  add_com ("use_ib_break", class_obscure, use_ib_breakpoints_command,
           _("Set breakpoints by IB break."));
           _("Set breakpoints by IB break."));
  add_com ("use_dbt_break", class_obscure, use_dbt_breakpoints_command,
  add_com ("use_dbt_break", class_obscure, use_dbt_breakpoints_command,
           _("Set breakpoints by dbt."));
           _("Set breakpoints by dbt."));
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.