/* 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 "gdb_bfd.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)
    xsnprintf (hostname, sizeof (hostname), "localhost:%d", SDIPORT);
  else
    {
      port_str = strchr (args, ':');
      if (port_str == NULL)
	xsnprintf (hostname, sizeof (hostname), "%s:%d", args, SDIPORT);
      else
	xsnprintf (hostname, sizeof (hostname), "%s", 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 = gdb_bfd_open (filename, gnutarget, -1);
  if (pbfd == NULL)
    {
      perror_with_name (filename);
      return;
    }
  old_chain = make_cleanup_bfd_unref (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);
}
