/* Native-dependent code for OpenBSD/powerpc.

   Copyright (C) 2004-2016 Free Software Foundation, Inc.

   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 "gdbcore.h"
#include "inferior.h"
#include "regcache.h"

#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/signal.h>
#include <machine/frame.h>
#include <machine/pcb.h>
#include <machine/reg.h>

#include "ppc-tdep.h"
#include "ppcobsd-tdep.h"
#include "inf-ptrace.h"
#include "obsd-nat.h"
#include "bsd-kvm.h"

/* OpenBSD/powerpc didn't have PT_GETFPREGS/PT_SETFPREGS until release
   4.0.  On older releases the floating-point registers are handled by
   PT_GETREGS/PT_SETREGS, but fpscr wasn't available..  */

#ifdef PT_GETFPREGS

/* Returns true if PT_GETFPREGS fetches this register.  */

static int
getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  /* FIXME: jimb/2004-05-05: Some PPC variants don't have floating
     point registers.  Traditionally, GDB's register set has still
     listed the floating point registers for such machines, so this
     code is harmless.  However, the new E500 port actually omits the
     floating point registers entirely from the register set --- they
     don't even have register numbers assigned to them.

     It's not clear to me how best to update this code, so this assert
     will alert the first person to encounter the NetBSD/E500
     combination to the problem.  */
  gdb_assert (ppc_floating_point_unit_p (gdbarch));

  return ((regnum >= tdep->ppc_fp0_regnum
           && regnum < tdep->ppc_fp0_regnum + ppc_num_fprs)
	  || regnum == tdep->ppc_fpscr_regnum);
}

#endif /* PT_GETFPREGS */

/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
   for all registers.  */

static void
ppcobsd_fetch_registers (struct target_ops *ops,
			 struct regcache *regcache, int regnum)
{
  struct reg regs;

  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
    perror_with_name (_("Couldn't get registers"));

  ppc_supply_gregset (&ppcobsd_gregset, regcache, -1,
		      &regs, sizeof regs);
#ifndef PT_GETFPREGS
  ppc_supply_fpregset (&ppcobsd_gregset, regcache, -1,
		       &regs, sizeof regs);
#endif

#ifdef PT_GETFPREGS
  if (regnum == -1
      || getfpregs_supplies (get_regcache_arch (regcache), regnum))
    {
      struct fpreg fpregs;

      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't get floating point status"));

      ppc_supply_fpregset (&ppcobsd_fpregset, regcache, -1,
			   &fpregs, sizeof fpregs);
    }
#endif
}

/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
   this for all registers.  */

static void
ppcobsd_store_registers (struct target_ops *ops,
			 struct regcache *regcache, int regnum)
{
  struct reg regs;

  if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid),
	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
    perror_with_name (_("Couldn't get registers"));

  ppc_collect_gregset (&ppcobsd_gregset, regcache,
		       regnum, &regs, sizeof regs);
#ifndef PT_GETFPREGS
  ppc_collect_fpregset (&ppcobsd_gregset, regcache,
			regnum, &regs, sizeof regs);
#endif

  if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid),
	      (PTRACE_TYPE_ARG3) &regs, 0) == -1)
    perror_with_name (_("Couldn't write registers"));

#ifdef PT_GETFPREGS
  if (regnum == -1
      || getfpregs_supplies (get_regcache_arch (regcache), regnum))
    {
      struct fpreg fpregs;

      if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't get floating point status"));

      ppc_collect_fpregset (&ppcobsd_fpregset, regcache,
			    regnum, &fpregs, sizeof fpregs);

      if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid),
		  (PTRACE_TYPE_ARG3) &fpregs, 0) == -1)
	perror_with_name (_("Couldn't write floating point status"));
    }
#endif
}


static int
ppcobsd_supply_pcb (struct regcache *regcache, struct pcb *pcb)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  struct switchframe sf;
  struct callframe cf;
  int i, regnum;

  /* The following is true for OpenBSD 3.7:

     The pcb contains %r1 (the stack pointer) at the point of the
     context switch in cpu_switch().  At that point we have a stack
     frame as described by `struct switchframe', and below that a call
     frame as described by `struct callframe'.  From this information
     we reconstruct the register state as it would look when we are in
     cpu_switch().  */

  /* The stack pointer shouldn't be zero.  */
  if (pcb->pcb_sp == 0)
    return 0;

  read_memory (pcb->pcb_sp, (gdb_byte *)&sf, sizeof sf);
  regcache_raw_supply (regcache, gdbarch_sp_regnum (gdbarch), &sf.sp);
  regcache_raw_supply (regcache, tdep->ppc_cr_regnum, &sf.cr);
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 2, &sf.fixreg2);
  for (i = 0, regnum = tdep->ppc_gp0_regnum + 13; i < 19; i++, regnum++)
    regcache_raw_supply (regcache, regnum, &sf.fixreg[i]);

  read_memory (sf.sp, (gdb_byte *)&cf, sizeof cf);
  regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch), &cf.lr);
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 30, &cf.r30);
  regcache_raw_supply (regcache, tdep->ppc_gp0_regnum + 31, &cf.r31);

  return 1;
}


/* Provide a prototype to silence -Wmissing-prototypes.  */
void _initialize_ppcobsd_nat (void);

void
_initialize_ppcobsd_nat (void)
{
  struct target_ops *t;

  /* Add in local overrides.  */
  t = inf_ptrace_target ();
  t->to_fetch_registers = ppcobsd_fetch_registers;
  t->to_store_registers = ppcobsd_store_registers;
  obsd_add_target (t);

  /* General-purpose registers.  */
  ppcobsd_reg_offsets.r0_offset = offsetof (struct reg, gpr);
  ppcobsd_reg_offsets.gpr_size = 4;
  ppcobsd_reg_offsets.xr_size = 4;
  ppcobsd_reg_offsets.pc_offset = offsetof (struct reg, pc);
  ppcobsd_reg_offsets.ps_offset = offsetof (struct reg, ps);
  ppcobsd_reg_offsets.cr_offset = offsetof (struct reg, cnd);
  ppcobsd_reg_offsets.lr_offset = offsetof (struct reg, lr);
  ppcobsd_reg_offsets.ctr_offset = offsetof (struct reg, cnt);
  ppcobsd_reg_offsets.xer_offset = offsetof (struct reg, xer);
  ppcobsd_reg_offsets.mq_offset = offsetof (struct reg, mq);

  /* Floating-point registers.  */
  ppcobsd_reg_offsets.f0_offset = offsetof (struct reg, fpr);
  ppcobsd_reg_offsets.fpscr_offset = -1;
#ifdef PT_GETFPREGS
  ppcobsd_fpreg_offsets.f0_offset = offsetof (struct fpreg, fpr);
  ppcobsd_fpreg_offsets.fpscr_offset = offsetof (struct fpreg, fpscr);
  ppcobsd_fpreg_offsets.fpscr_size = 4;
#endif

  /* AltiVec registers.  */
  ppcobsd_reg_offsets.vr0_offset = offsetof (struct vreg, vreg);
  ppcobsd_reg_offsets.vscr_offset = offsetof (struct vreg, vscr);
  ppcobsd_reg_offsets.vrsave_offset = offsetof (struct vreg, vrsave);

  /* Support debugging kernel virtual memory images.  */
  bsd_kvm_add_target (ppcobsd_supply_pcb);
}
