/* sparc-dependent portions of the RPC protocol
   used with a VxWorks target 

   Contributed by Wind River Systems.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include <stdio.h>
#include "defs.h"

#include "vx-share/regPacket.h"
#include "frame.h"
#include "inferior.h"
#include "gdb_wait.h"
#include "target.h"
#include "gdbcore.h"
#include "command.h"
#include "symtab.h"
#include "symfile.h"		/* for struct complaint */

#include "gdb_string.h"
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>

#ifdef _AIX			/* IBM claims "void *malloc()" not char * */
#define malloc bogon_malloc
#endif

#include <rpc/rpc.h>
#include <sys/time.h>		/* UTek's <rpc/rpc.h> doesn't #incl this */
#include <netdb.h>
#include "vx-share/ptrace.h"
#include "vx-share/xdr_ptrace.h"
#include "vx-share/xdr_ld.h"
#include "vx-share/xdr_rdb.h"
#include "vx-share/dbgRpcLib.h"

/* get rid of value.h if possible */
#include <value.h>
#include <symtab.h>

/* Flag set if target has fpu */

extern int target_has_fp;

/* sparc floating point format descriptor, from "sparc-tdep.c."  */

extern struct ext_format ext_format_sparc;

/* Generic register read/write routines in remote-vx.c.  */

extern void net_read_registers ();
extern void net_write_registers ();

/* Read a register or registers from the VxWorks target.
   REGNO is the register to read, or -1 for all; currently,
   it is ignored.  FIXME look at regno to improve efficiency.  */

void
vx_read_register (regno)
     int regno;
{
  char sparc_greg_packet[SPARC_GREG_PLEN];
  char sparc_fpreg_packet[SPARC_FPREG_PLEN];
  CORE_ADDR sp;

  /* Get general-purpose registers.  When copying values into
     registers [], don't assume that a location in registers []
     is properly aligned for the target data type.  */

  net_read_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_GETREGS);

  /* Now copy the register values into registers[].
     Note that this code depends on the ordering of the REGNUMs
     as defined in "tm-sparc.h".  */

  bcopy (&sparc_greg_packet[SPARC_R_G0],
	 &registers[REGISTER_BYTE (G0_REGNUM)], 32 * SPARC_GREG_SIZE);
  bcopy (&sparc_greg_packet[SPARC_R_Y],
	 &registers[REGISTER_BYTE (Y_REGNUM)], 6 * SPARC_GREG_SIZE);

  /* Now write the local and in registers to the register window
     spill area in the frame.  VxWorks does not do this for the
     active frame automatically; it greatly simplifies debugging
     (FRAME_FIND_SAVED_REGS, in particular, depends on this).  */

  sp = extract_address (&registers[REGISTER_BYTE (SP_REGNUM)],
			REGISTER_RAW_SIZE (CORE_ADDR));
  write_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
		16 * REGISTER_RAW_SIZE (L0_REGNUM));

  /* If the target has floating point registers, fetch them.
     Otherwise, zero the floating point register values in
     registers[] for good measure, even though we might not
     need to.  */

  if (target_has_fp)
    {
      net_read_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN,
			  PTRACE_GETFPREGS);
      bcopy (&sparc_fpreg_packet[SPARC_R_FP0],
	     &registers[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE);
      bcopy (&sparc_fpreg_packet[SPARC_R_FSR],
	     &registers[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE);
    }
  else
    {
      bzero (&registers[REGISTER_BYTE (FP0_REGNUM)], 32 * SPARC_FPREG_SIZE);
      bzero (&registers[REGISTER_BYTE (FPS_REGNUM)], 1 * SPARC_FPREG_SIZE);
    }

  /* Mark the register cache valid.  */

  registers_fetched ();
}

/* Store a register or registers into the VxWorks target.
   REGNO is the register to store, or -1 for all; currently,
   it is ignored.  FIXME look at regno to improve efficiency.  */

void
vx_write_register (regno)
     int regno;
{
  char sparc_greg_packet[SPARC_GREG_PLEN];
  char sparc_fpreg_packet[SPARC_FPREG_PLEN];
  int in_gp_regs;
  int in_fp_regs;
  CORE_ADDR sp;

  /* Store general purpose registers.  When copying values from
     registers [], don't assume that a location in registers []
     is properly aligned for the target data type.  */

  in_gp_regs = 1;
  in_fp_regs = 1;
  if (regno >= 0)
    {
      if ((G0_REGNUM <= regno && regno <= I7_REGNUM)
	  || (Y_REGNUM <= regno && regno <= NPC_REGNUM))
	in_fp_regs = 0;
      else
	in_gp_regs = 0;
    }
  if (in_gp_regs)
    {
      bcopy (&registers[REGISTER_BYTE (G0_REGNUM)],
	     &sparc_greg_packet[SPARC_R_G0], 32 * SPARC_GREG_SIZE);
      bcopy (&registers[REGISTER_BYTE (Y_REGNUM)],
	     &sparc_greg_packet[SPARC_R_Y], 6 * SPARC_GREG_SIZE);

      net_write_registers (sparc_greg_packet, SPARC_GREG_PLEN, PTRACE_SETREGS);

      /* If this is a local or in register, or we're storing all
         registers, update the register window spill area.  */

      if (regno < 0 || (L0_REGNUM <= regno && regno <= I7_REGNUM))
	{
	  sp = extract_address (&registers[REGISTER_BYTE (SP_REGNUM)],
				REGISTER_RAW_SIZE (CORE_ADDR));
	  write_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
			16 * REGISTER_RAW_SIZE (L0_REGNUM));
	}
    }

  /* Store floating point registers if the target has them.  */

  if (in_fp_regs && target_has_fp)
    {
      bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
	     &sparc_fpreg_packet[SPARC_R_FP0], 32 * SPARC_FPREG_SIZE);
      bcopy (&registers[REGISTER_BYTE (FPS_REGNUM)],
	     &sparc_fpreg_packet[SPARC_R_FSR], 1 * SPARC_FPREG_SIZE);

      net_write_registers (sparc_fpreg_packet, SPARC_FPREG_PLEN,
			   PTRACE_SETFPREGS);
    }
}
