/* syscalls.c --- implement system calls for the RX simulator.

Copyright (C) 2005, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
Contributed by Red Hat, Inc.

This file is part of the GNU simulators.

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 "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>

#include "gdb/callback.h"

#include "cpu.h"
#include "mem.h"
#include "syscalls.h"

#include "syscall.h"

/* The current syscall callbacks we're using.  */
static struct host_callback_struct *callbacks;

void
set_callbacks (struct host_callback_struct *cb)
{
  callbacks = cb;
}


/* Arguments 1..4 are in R1..R4, remainder on stack.

   Return value in R1..R4 as needed.
     structs bigger than 16 bytes: pointer pushed on stack last

   We only support arguments that fit in general registers.

   The system call number is in R5.  We expect ssycalls to look like
   this in libgloss:

   _exit:
   	mov	#SYS_exit, r5
	int	#255
	rts
*/

int argp, stackp;

static int
arg ()
{
  int rv = 0;
  argp++;

  if (argp < 4)
    return get_reg (argp);

  rv = mem_get_si (get_reg (sp) + stackp);
  stackp += 4;
  return rv;
}

static void
read_target (char *buffer, int address, int count, int asciiz)
{
  char byte;
  while (count > 0)
    {
      byte = mem_get_qi (address++);
      *buffer++ = byte;
      if (asciiz && (byte == 0))
	return;
      count--;
    }
}

static void
write_target (char *buffer, int address, int count, int asciiz)
{
  char byte;
  while (count > 0)
    {
      byte = *buffer++;
      mem_put_qi (address++, byte);
      if (asciiz && (byte == 0))
	return;
      count--;
    }
}

#define PTRSZ (A16 ? 2 : 3)

static char *callnames[] = {
  "SYS_zero",
  "SYS_exit",
  "SYS_open",
  "SYS_close",
  "SYS_read",
  "SYS_write",
  "SYS_lseek",
  "SYS_unlink",
  "SYS_getpid",
  "SYS_kill",
  "SYS_fstat",
  "SYS_sbrk",
  "SYS_argvlen",
  "SYS_argv",
  "SYS_chdir",
  "SYS_stat",
  "SYS_chmod",
  "SYS_utime",
  "SYS_time",
  "SYS_gettimeofday",
  "SYS_times",
  "SYS_link"
};

int
rx_syscall (int id)
{
  static char buf[256];
  int rv;

  argp = 0;
  stackp = 4;
  if (trace)
    printf ("\033[31m/* SYSCALL(%d) = %s */\033[0m\n", id, id <= SYS_link ? callnames[id] : "unknown");
  switch (id)
    {
    case SYS_exit:
      {
	int ec = arg ();
	if (verbose)
	  printf ("[exit %d]\n", ec);
	return RX_MAKE_EXITED (ec);
      }
      break;

    case SYS_open:
      {
	int path = arg ();
	/* The open function is defined as taking a variable number of arguments
	   because the third parameter to it is optional:
	     open (const char * filename, int flags, ...);
	   Hence the oflags and cflags arguments will be on the stack and we need
	   to skip the (empty) argument registers r3 and r4.  */
	argp = 4;
	int oflags = arg ();
	int cflags = arg ();

	read_target (buf, path, 256, 1);
	if (trace)
	  printf ("open(\"%s\",0x%x,%#o) = ", buf, oflags, cflags);

	if (callbacks)
	  /* The callback vector ignores CFLAGS.  */
	  rv = callbacks->open (callbacks, buf, oflags);
	else
	  {
	    int h_oflags = 0;

	    if (oflags & 0x0001)
	      h_oflags |= O_WRONLY;
	    if (oflags & 0x0002)
	      h_oflags |= O_RDWR;
	    if (oflags & 0x0200)
	      h_oflags |= O_CREAT;
	    if (oflags & 0x0008)
	      h_oflags |= O_APPEND;
	    if (oflags & 0x0400)
	      h_oflags |= O_TRUNC;
	    rv = open (buf, h_oflags, cflags);
	  }
	if (trace)
	  printf ("%d\n", rv);
	put_reg (1, rv);
      }
      break;

    case SYS_close:
      {
	int fd = arg ();

	if (callbacks)
	  rv = callbacks->close (callbacks, fd);
	else if (fd > 2)
	  rv = close (fd);
	else
	  rv = 0;
	if (trace)
	  printf ("close(%d) = %d\n", fd, rv);
	put_reg (1, rv);
      }
      break;

    case SYS_read:
      {
	int fd = arg ();
	int addr = arg ();
	int count = arg ();

	if (count > sizeof (buf))
	  count = sizeof (buf);
	if (callbacks)
	  rv = callbacks->read (callbacks, fd, buf, count);
	else
	  rv = read (fd, buf, count);
	if (trace)
	  printf ("read(%d,%d) = %d\n", fd, count, rv);
	if (rv > 0)
	  write_target (buf, addr, rv, 0);
	put_reg (1, rv);
      }
      break;

    case SYS_write:
      {
	int fd = arg ();
	int addr = arg ();
	int count = arg ();

	if (count > sizeof (buf))
	  count = sizeof (buf);
	if (trace)
	  printf ("write(%d,0x%x,%d)\n", fd, addr, count);
	read_target (buf, addr, count, 0);
	if (trace)
	  fflush (stdout);
	if (callbacks)
	  rv = callbacks->write (callbacks, fd, buf, count);
	else
	  rv = write (fd, buf, count);
	if (trace)
	  printf ("write(%d,%d) = %d\n", fd, count, rv);
	put_reg (1, rv);
      }
      break;

    case SYS_getpid:
      put_reg (1, 42);
      break;

    case SYS_gettimeofday:
      {
	int tvaddr = arg ();
	struct timeval tv;

	rv = gettimeofday (&tv, 0);
	if (trace)
	  printf ("gettimeofday: %ld sec %ld usec to 0x%x\n", tv.tv_sec,
		  tv.tv_usec, tvaddr);
	mem_put_si (tvaddr, tv.tv_sec);
	mem_put_si (tvaddr + 4, tv.tv_usec);
	put_reg (1, rv);
      }
      break;

    case SYS_kill:
      {
	int pid = arg ();
	int sig = arg ();
	if (pid == 42)
	  {
	    if (verbose)
	      printf ("[signal %d]\n", sig);
	    return RX_MAKE_STOPPED (sig);
	  }
      }
      break;

    case 11:
      {
	int heaptop_arg = arg ();
	if (trace)
	  printf ("sbrk: heap top set to %x\n", heaptop_arg);
	heaptop = heaptop_arg;
	if (heapbottom == 0)
	  heapbottom = heaptop_arg;
      }
      break;

    case 255:
      {
	int addr = arg ();
	mem_put_si (addr, rx_cycles + mem_usage_cycles());
      }
      break;

    }
  return RX_MAKE_STEPPED ();
}
