/* Low level interface to SPUs, for the remote server for GDB.
   Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.

   Contributed by Ulrich Weigand <uweigand@de.ibm.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 "server.h"

#include <sys/wait.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/syscall.h>

/* Some older glibc versions do not define this.  */
#ifndef __WNOTHREAD
#define __WNOTHREAD     0x20000000      /* Don't wait on children of other
				           threads in this group */
#endif

#define PTRACE_TYPE_RET long
#define PTRACE_TYPE_ARG3 long

/* Number of registers.  */
#define SPU_NUM_REGS         130
#define SPU_NUM_CORE_REGS    128

/* Special registers.  */
#define SPU_ID_REGNUM        128
#define SPU_PC_REGNUM        129

/* PPU side system calls.  */
#define INSTR_SC	0x44000002
#define NR_spu_run	0x0116

/* Get current thread ID (Linux task ID).  */
#define current_tid ((struct inferior_list_entry *)current_inferior)->id

/* These are used in remote-utils.c.  */
int using_threads = 0;

/* Defined in auto-generated file reg-spu.c.  */
void init_registers_spu (void);


/* Fetch PPU register REGNO.  */
static CORE_ADDR
fetch_ppc_register (int regno)
{
  PTRACE_TYPE_RET res;

  int tid = current_tid;

#ifndef __powerpc64__
  /* If running as a 32-bit process on a 64-bit system, we attempt
     to get the full 64-bit register content of the target process.
     If the PPC special ptrace call fails, we're on a 32-bit system;
     just fall through to the regular ptrace call in that case.  */
  {
    char buf[8];

    errno = 0;
    ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
	    (PTRACE_TYPE_ARG3) (regno * 8), buf);
    if (errno == 0)
      ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
	      (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
    if (errno == 0)
      return (CORE_ADDR) *(unsigned long long *)buf;
  }
#endif

  errno = 0;
  res = ptrace (PT_READ_U, tid,
	 	(PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
  if (errno != 0)
    {
      char mess[128];
      sprintf (mess, "reading PPC register #%d", regno);
      perror_with_name (mess);
    }

  return (CORE_ADDR) (unsigned long) res;
}

/* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID.  */
static int
fetch_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET *word)
{
  errno = 0;

#ifndef __powerpc64__
  if (memaddr >> 32)
    {
      unsigned long long addr_8 = (unsigned long long) memaddr;
      ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
    }
  else
#endif
    *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);

  return errno;
}

/* Store WORD into PPU memory at (aligned) MEMADDR in thread TID.  */
static int
store_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET word)
{
  errno = 0;

#ifndef __powerpc64__
  if (memaddr >> 32)
    {
      unsigned long long addr_8 = (unsigned long long) memaddr;
      ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
    }
  else
#endif
    ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word);

  return errno;
}

/* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR.  */
static int
fetch_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
  int i, ret;

  CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
  int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
	       / sizeof (PTRACE_TYPE_RET));
  PTRACE_TYPE_RET *buffer;

  int tid = current_tid;

  buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
  for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
    if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[i])) != 0)
      return ret;

  memcpy (myaddr,
	  (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
	  len);

  return 0;
}

/* Store LEN bytes from MYADDR to PPU memory at MEMADDR.  */
static int
store_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
  int i, ret;

  CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
  int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
	       / sizeof (PTRACE_TYPE_RET));
  PTRACE_TYPE_RET *buffer;

  int tid = current_tid;

  buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));

  if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
    if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[0])) != 0)
      return ret;

  if (count > 1)
    if ((ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
					       * sizeof (PTRACE_TYPE_RET),
				   &buffer[count - 1])) != 0)
      return ret;

  memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
          myaddr, len);

  for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
    if ((ret = store_ppc_memory_1 (tid, addr, buffer[i])) != 0)
      return ret;

  return 0;
}


/* If the PPU thread is currently stopped on a spu_run system call,
   return to FD and ADDR the file handle and NPC parameter address
   used with the system call.  Return non-zero if successful.  */
static int 
parse_spufs_run (int *fd, CORE_ADDR *addr)
{
  char buf[4];
  CORE_ADDR pc = fetch_ppc_register (32);  /* nip */

  /* Fetch instruction preceding current NIP.  */
  if (fetch_ppc_memory (pc-4, buf, 4) != 0)
    return 0;
  /* It should be a "sc" instruction.  */
  if (*(unsigned int *)buf != INSTR_SC)
    return 0;
  /* System call number should be NR_spu_run.  */
  if (fetch_ppc_register (0) != NR_spu_run)
    return 0;

  /* Register 3 contains fd, register 4 the NPC param pointer.  */
  *fd = fetch_ppc_register (34);  /* orig_gpr3 */
  *addr = fetch_ppc_register (4);
  return 1;
}


/* Copy LEN bytes at OFFSET in spufs file ANNEX into/from READBUF or WRITEBUF,
   using the /proc file system.  */
static int
spu_proc_xfer_spu (const char *annex, unsigned char *readbuf,
		   const unsigned char *writebuf,
		   CORE_ADDR offset, int len)
{
  char buf[128];
  int fd = 0;
  int ret = -1;

  if (!annex)
    return 0;

  sprintf (buf, "/proc/%ld/fd/%s", current_tid, annex);
  fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
  if (fd <= 0)
    return -1;

  if (offset != 0
      && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
    {
      close (fd);
      return 0;
    }

  if (writebuf)
    ret = write (fd, writebuf, (size_t) len);
  else if (readbuf)
    ret = read (fd, readbuf, (size_t) len);

  close (fd);
  return ret;
}


/* Start an inferior process and returns its pid.
   ALLARGS is a vector of program-name and args. */
static int
spu_create_inferior (char *program, char **allargs)
{
  int pid;

  pid = fork ();
  if (pid < 0)
    perror_with_name ("fork");

  if (pid == 0)
    {
      ptrace (PTRACE_TRACEME, 0, 0, 0);

      setpgid (0, 0);

      execv (program, allargs);
      if (errno == ENOENT)
	execvp (program, allargs);

      fprintf (stderr, "Cannot exec %s: %s.\n", program,
	       strerror (errno));
      fflush (stderr);
      _exit (0177);
    }

  add_thread (pid, NULL, pid);
  return pid;
}

/* Attach to an inferior process.  */
int
spu_attach (unsigned long  pid)
{
  if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
    {
      fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid,
	       strerror (errno), errno);
      fflush (stderr);
      _exit (0177);
    }

  add_thread (pid, NULL, pid);
  return 0;
}

/* Kill the inferior process.  */
static void
spu_kill (void)
{
  ptrace (PTRACE_KILL, current_tid, 0, 0);
}

/* Detach from inferior process.  */
static int
spu_detach (void)
{
  ptrace (PTRACE_DETACH, current_tid, 0, 0);
  return 0;
}

static void
spu_join (void)
{
  int status, ret;

  do {
    ret = waitpid (current_tid, &status, 0);
    if (WIFEXITED (status) || WIFSIGNALED (status))
      break;
  } while (ret != -1 || errno != ECHILD);
}

/* Return nonzero if the given thread is still alive.  */
static int
spu_thread_alive (unsigned long tid)
{
  return tid == current_tid;
}

/* Resume process.  */
static void
spu_resume (struct thread_resume *resume_info)
{
  while (resume_info->thread != -1
	 && resume_info->thread != current_tid)
    resume_info++;

  if (resume_info->leave_stopped)
    return;

  /* We don't support hardware single-stepping right now, assume
     GDB knows to use software single-stepping.  */
  if (resume_info->step)
    fprintf (stderr, "Hardware single-step not supported.\n");

  regcache_invalidate ();

  errno = 0;
  ptrace (PTRACE_CONT, current_tid, 0, resume_info->sig);
  if (errno)
    perror_with_name ("ptrace");
}

/* Wait for process, returns status.  */
static unsigned char
spu_wait (char *status)
{
  int tid = current_tid;
  int w;
  int ret;

  while (1)
    {
      ret = waitpid (tid, &w, WNOHANG | __WALL | __WNOTHREAD);

      if (ret == -1)
	{
	  if (errno != ECHILD)
	    perror_with_name ("waitpid");
	}
      else if (ret > 0)
	break;

      usleep (1000);
    }

  /* On the first wait, continue running the inferior until we are
     blocked inside an spu_run system call.  */
  if (!server_waiting)
    {
      int fd;
      CORE_ADDR addr;

      while (!parse_spufs_run (&fd, &addr))
	{
	  ptrace (PT_SYSCALL, tid, (PTRACE_TYPE_ARG3) 0, 0);
	  waitpid (tid, NULL, __WALL | __WNOTHREAD);
	}
    }

  if (WIFEXITED (w))
    {
      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
      *status = 'W';
      clear_inferiors ();
      return ((unsigned char) WEXITSTATUS (w));
    }
  else if (!WIFSTOPPED (w))
    {
      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
      *status = 'X';
      clear_inferiors ();
      return ((unsigned char) WTERMSIG (w));
    }

  /* After attach, we may have received a SIGSTOP.  Do not return this
     as signal to GDB, or else it will try to continue with SIGSTOP ...  */
  if (!server_waiting)
    {
      *status = 'T';
      return 0;
    }

  *status = 'T';
  return ((unsigned char) WSTOPSIG (w));
}

/* Fetch inferior registers.  */
static void
spu_fetch_registers (int regno)
{
  int fd;
  CORE_ADDR addr;

  /* ??? Some callers use 0 to mean all registers.  */
  if (regno == 0)
    regno = -1;

  /* We must be stopped on a spu_run system call.  */
  if (!parse_spufs_run (&fd, &addr))
    return;

  /* The ID register holds the spufs file handle.  */
  if (regno == -1 || regno == SPU_ID_REGNUM)
    supply_register (SPU_ID_REGNUM, (char *)&fd);

  /* The NPC register is found at ADDR.  */
  if (regno == -1 || regno == SPU_PC_REGNUM)
    {
      char buf[4];
      if (fetch_ppc_memory (addr, buf, 4) == 0)
	supply_register (SPU_PC_REGNUM, buf);
    }

  /* The GPRs are found in the "regs" spufs file.  */
  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
    {
      unsigned char buf[16*SPU_NUM_CORE_REGS];
      char annex[32];
      int i;

      sprintf (annex, "%d/regs", fd);
      if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
	for (i = 0; i < SPU_NUM_CORE_REGS; i++)
	  supply_register (i, buf + i*16);
    }
}

/* Store inferior registers.  */
static void
spu_store_registers (int regno)
{
  int fd;
  CORE_ADDR addr;

  /* ??? Some callers use 0 to mean all registers.  */
  if (regno == 0)
    regno = -1;

  /* We must be stopped on a spu_run system call.  */
  if (!parse_spufs_run (&fd, &addr))
    return;

  /* The NPC register is found at ADDR.  */
  if (regno == -1 || regno == SPU_PC_REGNUM)
    {
      char buf[4];
      collect_register (SPU_PC_REGNUM, buf);
      store_ppc_memory (addr, buf, 4);
    }

  /* The GPRs are found in the "regs" spufs file.  */
  if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
    {
      unsigned char buf[16*SPU_NUM_CORE_REGS];
      char annex[32];
      int i;

      for (i = 0; i < SPU_NUM_CORE_REGS; i++)
	collect_register (i, buf + i*16);

      sprintf (annex, "%d/regs", fd);
      spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
    }
}

/* Copy LEN bytes from inferior's memory starting at MEMADDR
   to debugger memory starting at MYADDR.  */
static int
spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
  int fd, ret;
  CORE_ADDR addr;
  char annex[32];

  /* We must be stopped on a spu_run system call.  */
  if (!parse_spufs_run (&fd, &addr))
    return 0;

  /* Use the "mem" spufs file to access SPU local store.  */
  sprintf (annex, "%d/mem", fd);
  ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len);
  return ret == len ? 0 : EIO;
}

/* Copy LEN bytes of data from debugger memory at MYADDR
   to inferior's memory at MEMADDR.
   On failure (cannot write the inferior)
   returns the value of errno.  */
static int
spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
{
  int fd, ret;
  CORE_ADDR addr;
  char annex[32];

  /* We must be stopped on a spu_run system call.  */
  if (!parse_spufs_run (&fd, &addr))
    return 0;

  /* Use the "mem" spufs file to access SPU local store.  */
  sprintf (annex, "%d/mem", fd);
  ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len);
  return ret == len ? 0 : EIO;
}

/* Look up special symbols -- unneded here.  */
static void
spu_look_up_symbols (void)
{
}

/* Send signal to inferior.  */
static void
spu_request_interrupt (void)
{
  syscall (SYS_tkill, current_tid, SIGINT);
}

static struct target_ops spu_target_ops = {
  spu_create_inferior,
  spu_attach,
  spu_kill,
  spu_detach,
  spu_join,
  spu_thread_alive,
  spu_resume,
  spu_wait,
  spu_fetch_registers,
  spu_store_registers,
  spu_read_memory,
  spu_write_memory,
  spu_look_up_symbols,
  spu_request_interrupt,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  spu_proc_xfer_spu,
  hostio_last_error_from_errno,
};

void
initialize_low (void)
{
  static const unsigned char breakpoint[] = { 0x00, 0x00, 0x3f, 0xff };

  set_target_ops (&spu_target_ops);
  set_breakpoint_data (breakpoint, sizeof breakpoint);
  init_registers_spu ();
}
