/* Copyright 2007-2019 Free Software Foundation, Inc.

   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/>.

   This file is part of the gdb testsuite.

   Contributed by Markus Deuling <deuling@de.ibm.com>.
   Tests for 'info spu' commands.  */

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <spu_mfcio.h>


/* PPE-assisted call interface.  */
void
send_to_ppe (unsigned int signalcode, unsigned int opcode, void *data)
{
  __vector unsigned int stopfunc =
    {
      signalcode,     /* stop */
      (opcode << 24) | (unsigned int) data,
      0x4020007f,     /* nop */
      0x35000000      /* bi $0 */
    };

  void (*f) (void) = (void *) &stopfunc;
  asm ("sync");
  f ();
}

/* PPE-assisted call to mmap from SPU.  */
unsigned long long
mmap_ea (unsigned long long start, size_t length,
         int prot, int flags, int fd, off_t offset)
{
  struct mmap_args
    {
      unsigned long long start __attribute__ ((aligned (16)));
      size_t length __attribute__ ((aligned (16)));
      int prot __attribute__ ((aligned (16)));
      int flags __attribute__ ((aligned (16)));
      int fd __attribute__ ((aligned (16)));
      off_t offset __attribute__ ((aligned (16)));
    } args;

  args.start = start;
  args.length = length;
  args.prot = prot;
  args.flags = flags;
  args.fd = fd;
  args.offset = offset;

  send_to_ppe (0x2101, 11, &args);
  return args.start;
}

/* This works only in a Linux environment with <= 1024 open
   file descriptors for one process. Result is the file
   descriptor for the current context if available.  */
int
find_context_fd (void)
{
  int dir_fd = -1;
  int i;

  for (i = 0; i < 1024; i++)
    {
      struct stat stat;

      if (fstat (i, &stat) < 0)
        break;
      if (S_ISDIR (stat.st_mode))
        dir_fd = dir_fd == -1 ? i : -2;
    }
  return dir_fd < 0 ? -1 : dir_fd;
}

/* Open the context file and return the file handler.  */
int
open_context_file (int context_fd, char *name, int flags)
{
  char buf[128];

  if (context_fd < 0)
    return -1;

  sprintf (buf, "/proc/self/fd/%d/%s", context_fd, name);
  return open (buf, flags);
}


int
do_event_test ()
{
  spu_write_event_mask (MFC_MULTI_SRC_SYNC_EVENT); /* 0x1000 */  /* Marker Event */
  spu_write_event_mask (MFC_PRIV_ATTN_EVENT); /* 0x0800 */
  spu_write_event_mask (MFC_LLR_LOST_EVENT); /* 0x0400 */
  spu_write_event_mask (MFC_SIGNAL_NOTIFY_1_EVENT); /* 0x0200 */
  spu_write_event_mask (MFC_SIGNAL_NOTIFY_2_EVENT); /* 0x0100 */
  spu_write_event_mask (MFC_OUT_MBOX_AVAILABLE_EVENT); /* 0x0080 */
  spu_write_event_mask (MFC_OUT_INTR_MBOX_AVAILABLE_EVENT); /* 0x0040 */
  spu_write_event_mask (MFC_DECREMENTER_EVENT); /* 0x0020 */
  spu_write_event_mask (MFC_IN_MBOX_AVAILABLE_EVENT); /* 0x0010 */
  spu_write_event_mask (MFC_COMMAND_QUEUE_AVAILABLE_EVENT); /* 0x0008 */
  spu_write_event_mask (MFC_LIST_STALL_NOTIFY_EVENT); /* 0x0002 */
  spu_write_event_mask (MFC_TAG_STATUS_UPDATE_EVENT); /* 0x0001 */

  return 0;
}

int
do_dma_test ()
{
  #define MAP_FAILED      (-1ULL)
  #define PROT_READ       0x1
  #define MAP_PRIVATE     0x002
  #define BSIZE 128
  static char buf[BSIZE] __attribute__ ((aligned (128)));
  char *file = "/var/tmp/tmp_buf";
  struct stat fdstat;
  int fd, cnt;
  unsigned long long src;

  /* Create a file and fill it with some bytes.  */
  fd = open (file, O_CREAT | O_RDWR | O_TRUNC, 0777);
  if (fd == -1)
    return -1;
  memset ((void *)buf, '1', BSIZE);
  write (fd, buf, BSIZE);
  write (fd, buf, BSIZE);
  memset ((void *)buf, 0, BSIZE);

  if (fstat (fd, &fdstat) != 0
      || !fdstat.st_size)
    return -2;

  src = mmap_ea(0ULL, fdstat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
  if (src == MAP_FAILED)
    return -3;

  /* Copy some data via DMA.  */
  mfc_get (&buf, src, BSIZE, 5, 0, 0);   /* Marker DMA */
  mfc_write_tag_mask (1<<5);   /* Marker DMAWait */
  spu_mfcstat (MFC_TAG_UPDATE_ALL);

  /* Close the file.  */
  close (fd);

  return cnt;
}

int
do_mailbox_test ()
{
  /* Write to SPU Outbound Mailbox.  */
  if (spu_stat_out_mbox ())            /* Marker Mbox */
    spu_write_out_mbox (0x12345678);

  /* Write to SPU Outbound Interrupt Mailbox.  */
  if (spu_stat_out_intr_mbox ())
    spu_write_out_intr_mbox (0x12345678);

  return 0;       /* Marker MboxEnd */
}

int
do_signal_test ()
{
  struct stat fdstat;
  int context_fd = find_context_fd ();
  int ret, buf, fd;

  buf = 23;    /* Marker Signal */
  /* Write to signal1.  */
  fd = open_context_file (context_fd, "signal1", O_RDWR);
  if (fstat (fd, &fdstat) != 0)
    return -1;
  ret = write (fd, &buf, sizeof (int));
  close (fd);  /* Marker Signal1 */

  /* Write to signal2.  */
  fd = open_context_file (context_fd, "signal2", O_RDWR);
  if (fstat (fd, &fdstat) != 0)
    return -1;
  ret = write (fd, &buf, sizeof (int));
  close (fd);  /* Marker Signal2 */

  /* Read signal1.  */
  if (spu_stat_signal1 ())
    ret = spu_read_signal1 ();

  /* Read signal2.  */
  if (spu_stat_signal2 ())
    ret = spu_read_signal2 ();   /* Marker SignalRead */

  return 0;
}

int
main (unsigned long long speid, unsigned long long argp, 
      unsigned long long envp)
{
  int res;

  /* info spu event  */
  res = do_event_test ();

  /* info spu dma  */
  res = do_dma_test ();

  /* info spu mailbox  */
  res = do_mailbox_test ();

  /* info spu signal  */
  res = do_signal_test ();

  return 0;
}

