/* 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 "target.h"
#include "gdbcore.h"
#include "command.h"
#include "symtab.h"
#include "symfile.h"
#include "regcache.h"

#include "gdb_string.h"
#include <errno.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 (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],
	 &deprecated_registers[REGISTER_BYTE (G0_REGNUM)],
	 32 * SPARC_GREG_SIZE);
  bcopy (&sparc_greg_packet[SPARC_R_Y],
	 &deprecated_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.  */

  sp = extract_address (&deprecated_registers[REGISTER_BYTE (SP_REGNUM)],
			REGISTER_RAW_SIZE (SP_REGNUM));
  write_memory (sp, &deprecated_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],
	     &deprecated_registers[REGISTER_BYTE (FP0_REGNUM)],
	     32 * SPARC_FPREG_SIZE);
      bcopy (&sparc_fpreg_packet[SPARC_R_FSR],
	     &deprecated_registers[REGISTER_BYTE (FPS_REGNUM)],
	     1 * SPARC_FPREG_SIZE);
    }
  else
    {
      bzero (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM)],
	     32 * SPARC_FPREG_SIZE);
      bzero (&deprecated_registers[REGISTER_BYTE (FPS_REGNUM)],
	     1 * SPARC_FPREG_SIZE);
    }

  /* Mark the register cache valid.  */

  deprecated_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 (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 (&deprecated_registers[REGISTER_BYTE (G0_REGNUM)],
	     &sparc_greg_packet[SPARC_R_G0], 32 * SPARC_GREG_SIZE);
      bcopy (&deprecated_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 (&deprecated_registers[REGISTER_BYTE (SP_REGNUM)],
				REGISTER_RAW_SIZE (SP_REGNUM));
	  write_memory (sp, &deprecated_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 (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM)],
	     &sparc_fpreg_packet[SPARC_R_FP0], 32 * SPARC_FPREG_SIZE);
      bcopy (&deprecated_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);
    }
}
