/* Native-dependent code for GNU/Linux on LoongArch processors.

   Copyright (C) 2022-2024 Free Software Foundation, Inc.
   Contributed by Loongson Ltd.

   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 "elf/common.h"
#include "gregset.h"
#include "inferior.h"
#include "linux-nat-trad.h"
#include "loongarch-tdep.h"
#include "nat/gdb_ptrace.h"
#include "target-descriptions.h"

#include <asm/ptrace.h>

/* LoongArch Linux native additions to the default Linux support.  */

class loongarch_linux_nat_target final : public linux_nat_trad_target
{
public:
  /* Add our register access methods.  */
  void fetch_registers (struct regcache *, int) override;
  void store_registers (struct regcache *, int) override;

protected:
  /* Override linux_nat_trad_target methods.  */
  CORE_ADDR register_u_offset (struct gdbarch *gdbarch, int regnum,
			       int store_p) override;
};

/* Fill GDB's register array with the general-purpose, orig_a0, pc and badv
   register values from the current thread.  */

static void
fetch_gregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_gregset_t regset;

  if (regnum == -1 || (regnum >= 0 && regnum < 32)
      || regnum == LOONGARCH_ORIG_A0_REGNUM
      || regnum == LOONGARCH_PC_REGNUM
      || regnum == LOONGARCH_BADV_REGNUM)
  {
    struct iovec iov;

    iov.iov_base = &regset;
    iov.iov_len = sizeof (regset);

    if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
      perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
    else
      loongarch_gregset.supply_regset (nullptr, regcache, -1,
				       &regset, sizeof (regset));
  }
}

/* Store to the current thread the valid general-purpose, orig_a0, pc and badv
   register values in the GDB's register array.  */

static void
store_gregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_gregset_t regset;

  if (regnum == -1 || (regnum >= 0 && regnum < 32)
      || regnum == LOONGARCH_ORIG_A0_REGNUM
      || regnum == LOONGARCH_PC_REGNUM
      || regnum == LOONGARCH_BADV_REGNUM)
  {
    struct iovec iov;

    iov.iov_base = &regset;
    iov.iov_len = sizeof (regset);

    if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
      perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
    else
      {
	loongarch_gregset.collect_regset (nullptr, regcache, regnum,
					  &regset, sizeof (regset));
	if (ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
	  perror_with_name (_("Couldn't set NT_PRSTATUS registers"));
      }
  }
}

/* Fill GDB's register array with the fp, fcc and fcsr
   register values from the current thread.  */

static void
fetch_fpregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_fpregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
	perror_with_name (_("Couldn't get NT_FPREGSET registers"));
      else
	loongarch_fpregset.supply_regset (nullptr, regcache, -1,
					  &regset, sizeof (regset));
    }
}

/* Store to the current thread the valid fp, fcc and fcsr
   register values in the GDB's register array.  */

static void
store_fpregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_fpregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_FP_REGNUM && regnum <= LOONGARCH_FCSR_REGNUM))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
	perror_with_name (_("Couldn't get NT_FPREGSET registers"));
      else
	{
	  loongarch_fpregset.collect_regset (nullptr, regcache, regnum,
					     &regset, sizeof (regset));
	  if (ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
	    perror_with_name (_("Couldn't set NT_FPREGSET registers"));
	}
    }
}

/* Fill GDB's register array with the Loongson SIMD Extension
   register values from the current thread.  */

static void
fetch_lsxregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_lsxregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
	{
	  /* If kernel dose not support lsx, just return. */
	  if (errno == EINVAL)
	    return;

	  perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
	}
      else
	loongarch_lsxregset.supply_regset (nullptr, regcache, -1,
					   &regset, sizeof (regset));
    }
}

/* Store to the current thread the valid Loongson SIMD Extension
   register values in the GDB's register array.  */

static void
store_lsxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_lsxregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_LSX_REGNUM && regnum < LOONGARCH_FIRST_LASX_REGNUM))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
	{
	  /* If kernel dose not support lsx, just return. */
	  if (errno == EINVAL)
	    return;

	  perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
	}
      else
	{
	  loongarch_lsxregset.collect_regset (nullptr, regcache, regnum,
					     &regset, sizeof (regset));
	  if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LSX, (long) &iovec) < 0)
	    perror_with_name (_("Couldn't set NT_LARCH_LSX registers"));
	}
    }
}

/* Fill GDB's register array with the Loongson Advanced SIMD Extension
   register values from the current thread.  */

static void
fetch_lasxregs_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_lasxregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_LASX_REGNUM
	  && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
	{
	  /* If kernel dose not support lasx, just return. */
	  if (errno == EINVAL)
	    return;

	  perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
	}
      else
	loongarch_lasxregset.supply_regset (nullptr, regcache, -1,
					    &regset, sizeof (regset));
    }
}

/* Store to the current thread the valid Loongson Advanced SIMD Extension
   register values in the GDB's register array.  */

static void
store_lasxregs_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  elf_lasxregset_t regset;

  if ((regnum == -1)
      || (regnum >= LOONGARCH_FIRST_LASX_REGNUM
	  && regnum < LOONGARCH_FIRST_LASX_REGNUM + LOONGARCH_LINUX_NUM_LASXREGSET))
    {
      struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
	{
	  /* If kernel dose not support lasx, just return. */
	  if (errno == EINVAL)
	    return;

	  perror_with_name (_("Couldn't get NT_LARCH_LSX registers"));
	}
      else
	{
	  loongarch_lasxregset.collect_regset (nullptr, regcache, regnum,
					      &regset, sizeof (regset));
	  if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LASX, (long) &iovec) < 0)
	    perror_with_name (_("Couldn't set NT_LARCH_LASX registers"));
	}
    }
}


/* Fill GDB's register array with the lbt register values
   from the current thread.  */

static void
fetch_lbt_from_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  gdb_byte regset[LOONGARCH_LBT_REGS_SIZE];

  if (regnum == -1
      || (regnum >= LOONGARCH_FIRST_SCR_REGNUM
	  && regnum <= LOONGARCH_FTOP_REGNUM))
    {
      struct iovec iov;

      iov.iov_base = regset;
      iov.iov_len = LOONGARCH_LBT_REGS_SIZE;

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
	{
	  /* If kernel dose not support lbt, just return. */
	  if (errno == EINVAL)
	    return;
	  perror_with_name (_("Couldn't get NT_LARCH_LBT registers"));
	}
      else
	loongarch_lbtregset.supply_regset (nullptr, regcache, -1,
					   regset, LOONGARCH_LBT_REGS_SIZE);
    }
}

/* Store to the current thread the valid lbt register values
   in the GDB's register array.  */

static void
store_lbt_to_thread (struct regcache *regcache, int regnum, pid_t tid)
{
  gdb_byte regset[LOONGARCH_LBT_REGS_SIZE];

  if (regnum == -1
      || (regnum >= LOONGARCH_FIRST_SCR_REGNUM
	  && regnum <= LOONGARCH_FTOP_REGNUM))
    {
      struct iovec iov;

      iov.iov_base = regset;
      iov.iov_len = LOONGARCH_LBT_REGS_SIZE;

      if (ptrace (PTRACE_GETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
	{
	  /* If kernel dose not support lbt, just return. */
	  if (errno == EINVAL)
	    return;
	  perror_with_name (_("Couldn't get NT_LARCH_LBT registers"));
	}
      else
	{
	  loongarch_lbtregset.collect_regset (nullptr, regcache, regnum,
					    regset, LOONGARCH_LBT_REGS_SIZE);
	  if (ptrace (PTRACE_SETREGSET, tid, NT_LARCH_LBT, (long) &iov) < 0)
	    perror_with_name (_("Couldn't set NT_LARCH_LBT registers"));
	}
    }
}

/* Implement the "fetch_registers" target_ops method.  */

void
loongarch_linux_nat_target::fetch_registers (struct regcache *regcache,
					     int regnum)
{
  pid_t tid = get_ptrace_pid (regcache->ptid ());

  fetch_gregs_from_thread(regcache, regnum, tid);
  fetch_fpregs_from_thread(regcache, regnum, tid);
  fetch_lsxregs_from_thread(regcache, regnum, tid);
  fetch_lasxregs_from_thread(regcache, regnum, tid);
  fetch_lbt_from_thread (regcache, regnum, tid);
}

/* Implement the "store_registers" target_ops method.  */

void
loongarch_linux_nat_target::store_registers (struct regcache *regcache,
					     int regnum)
{
  pid_t tid = get_ptrace_pid (regcache->ptid ());

  store_gregs_to_thread (regcache, regnum, tid);
  store_fpregs_to_thread(regcache, regnum, tid);
  store_lsxregs_to_thread(regcache, regnum, tid);
  store_lasxregs_to_thread(regcache, regnum, tid);
  store_lbt_to_thread (regcache, regnum, tid);
}

/* Return the address in the core dump or inferior of register REGNO.  */

CORE_ADDR
loongarch_linux_nat_target::register_u_offset (struct gdbarch *gdbarch,
					       int regnum, int store_p)
{
  if (regnum >= 0 && regnum < 32)
    return regnum;
  else if (regnum == LOONGARCH_PC_REGNUM)
    return LOONGARCH_PC_REGNUM;
  else
    return -1;
}

static loongarch_linux_nat_target the_loongarch_linux_nat_target;

/* Wrapper functions.  These are only used by libthread_db.  */

void
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregset)
{
  loongarch_gregset.supply_regset (nullptr, regcache, -1, gregset,
				   sizeof (gdb_gregset_t));
}

void
fill_gregset (const struct regcache *regcache, gdb_gregset_t *gregset,
	      int regnum)
{
  loongarch_gregset.collect_regset (nullptr, regcache, regnum, gregset,
				    sizeof (gdb_gregset_t));
}

void
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregset)
{
  loongarch_fpregset.supply_regset (nullptr, regcache, -1, fpregset,
				    sizeof (gdb_fpregset_t));
}

void
fill_fpregset (const struct regcache *regcache, gdb_fpregset_t *fpregset,
	       int regnum)
{
  loongarch_fpregset.collect_regset (nullptr, regcache, regnum, fpregset,
				     sizeof (gdb_fpregset_t));
}

/* Initialize LoongArch Linux native support.  */

void _initialize_loongarch_linux_nat ();
void
_initialize_loongarch_linux_nat ()
{
  linux_target = &the_loongarch_linux_nat_target;
  add_inf_child_target (&the_loongarch_linux_nat_target);
}
