/*
 * arch/xtensa/kernel/syscall.c
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2001 - 2005 Tensilica Inc.
 * Copyright (C) 2000 Silicon Graphics, Inc.
 * Copyright (C) 1995 - 2000 by Ralf Baechle
 *
 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
 * Chris Zankel <chris@zankel.net>
 * Kevin Chea
 *
 */

#define DEBUG	0

#include <linux/linkage.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/mman.h>
#include <linux/sched.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/utsname.h>
#include <linux/unistd.h>
#include <linux/stringify.h>
#include <linux/syscalls.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/errno.h>
#include <asm/ptrace.h>
#include <asm/signal.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
#include <asm/mman.h>
#include <asm/shmparam.h>
#include <asm/page.h>

extern void do_syscall_trace(void);
typedef int (*syscall_t)(void *a0,...);
extern syscall_t sys_call_table[];
extern unsigned char sys_narg_table[];

/*
 * sys_pipe() is the normal C calling standard for creating a pipe. It's not
 * the way unix traditional does this, though.
 */

int sys_pipe(int __user *userfds)
{
	int fd[2];
	int error;

	error = do_pipe(fd);
	if (!error) {
		if (copy_to_user(userfds, fd, 2 * sizeof(int)))
			error = -EFAULT;
	}
	return error;
}

/*
 * Common code for old and new mmaps.
 */
long sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
	      unsigned long flags, unsigned long fd, unsigned long pgoff)
{
	int error = -EBADF;
	struct file * file = NULL;

	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
	if (!(flags & MAP_ANONYMOUS)) {
		file = fget(fd);
		if (!file)
			goto out;
	}

	down_write(&current->mm->mmap_sem);
	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
	up_write(&current->mm->mmap_sem);

	if (file)
		fput(file);
out:
	return error;
}

int sys_clone(struct pt_regs *regs)
{
	unsigned long clone_flags;
	unsigned long newsp;
	int __user *parent_tidptr, *child_tidptr;
	clone_flags = regs->areg[4];
	newsp = regs->areg[3];
	parent_tidptr = (int __user *)regs->areg[5];
	child_tidptr = (int __user *)regs->areg[6];
	if (!newsp)
		newsp = regs->areg[1];
	return do_fork(clone_flags,newsp,regs,0,parent_tidptr,child_tidptr);
}

/*
 * sys_execve() executes a new program.
 */

int sys_execve(struct pt_regs *regs)
{
	int error;
	char * filename;

	filename = getname((char *) (long)regs->areg[5]);
	error = PTR_ERR(filename);
	if (IS_ERR(filename))
		goto out;
	error = do_execve(filename, (char **) (long)regs->areg[3],
	                  (char **) (long)regs->areg[4], regs);
	putname(filename);

out:
	return error;
}

int sys_uname(struct old_utsname * name)
{
	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
		return 0;
	return -EFAULT;
}

/*
 * Build the string table for the builtin "poor man's strace".
 */

#if DEBUG
#define SYSCALL(fun, narg) #fun,
static char *sfnames[] = {
#include "syscalls.h"
};
#undef SYS
#endif

void system_call (struct pt_regs *regs)
{
	syscall_t syscall;
	unsigned long parm0, parm1, parm2, parm3, parm4, parm5;
	int nargs, res;
	unsigned int syscallnr;
	int ps;

#if DEBUG
	int i;
	unsigned long parms[6];
	char *sysname;
#endif

	regs->syscall = regs->areg[2];

	do_syscall_trace();

	/* Have to load after syscall_trace because strace
	 * sometimes changes regs->syscall.
	 */
	syscallnr = regs->syscall;

	parm0 = parm1 = parm2 = parm3 = parm4 = parm5 = 0;

	/* Restore interrupt level to syscall invoker's.
	 * If this were in assembly, we wouldn't disable
	 * interrupts in the first place:
	 */
	local_save_flags (ps);
	local_irq_restore((ps & ~XCHAL_PS_INTLEVEL_MASK) |
			  (regs->ps & XCHAL_PS_INTLEVEL_MASK) );

	if (syscallnr > __NR_Linux_syscalls) {
		regs->areg[2] = -ENOSYS;
		return;
	}

	syscall = sys_call_table[syscallnr];
	nargs = sys_narg_table[syscallnr];

	if (syscall == NULL) {
		regs->areg[2] = -ENOSYS;
		return;
	}

	/* There shouldn't be more than six arguments in the table! */

	if (nargs > 6)
		panic("Internal error - too many syscall arguments (%d)!\n",
		      nargs);

	/* Linux takes system-call arguments in registers.  The ABI
         * and Xtensa software conventions require the system-call
         * number in a2.  If an argument exists in a2, we move it to
         * the next available register.  Note that for improved
         * efficiency, we do NOT shift all parameters down one
         * register to maintain the original order.
	 *
         * At best case (zero arguments), we just write the syscall
         * number to a2.  At worst case (1 to 6 arguments), we move
         * the argument in a2 to the next available register, then
         * write the syscall number to a2.
	 *
         * For clarity, the following truth table enumerates all
         * possibilities.
	 *
         * arguments	syscall number	arg0, arg1, arg2, arg3, arg4, arg5
         * ---------	--------------	----------------------------------
	 *	0	      a2
	 *	1	      a2	a3
	 *	2	      a2	a4,   a3
	 *	3	      a2	a5,   a3,   a4
	 *	4	      a2	a6,   a3,   a4,   a5
	 *	5	      a2	a7,   a3,   a4,   a5,   a6
	 *	6	      a2	a8,   a3,   a4,   a5,   a6,   a7
	 */
	if (nargs) {
		parm0 = regs->areg[nargs+2];
		parm1 = regs->areg[3];
		parm2 = regs->areg[4];
		parm3 = regs->areg[5];
		parm4 = regs->areg[6];
		parm5 = regs->areg[7];
	} else /* nargs == 0 */
		parm0 = (unsigned long) regs;

#if DEBUG
	parms[0] = parm0;
	parms[1] = parm1;
	parms[2] = parm2;
	parms[3] = parm3;
	parms[4] = parm4;
	parms[5] = parm5;

	sysname = sfnames[syscallnr];
	if (strncmp(sysname, "sys_", 4) == 0)
		sysname = sysname + 4;

	printk("\017SYSCALL:I:%x:%d:%s  %s(", regs->pc, current->pid,
	       current->comm, sysname);
	for (i = 0; i < nargs; i++)
		printk((i>0) ? ", %#lx" : "%#lx", parms[i]);
	printk(")\n");
#endif

	res = syscall((void *)parm0, parm1, parm2, parm3, parm4, parm5);

#if DEBUG
	printk("\017SYSCALL:O:%d:%s  %s(",current->pid, current->comm, sysname);
	for (i = 0; i < nargs; i++)
		printk((i>0) ? ", %#lx" : "%#lx", parms[i]);
	if (res < 4096)
		printk(") = %d\n", res);
	else
		printk(") = %#x\n", res);
#endif /* DEBUG */

	regs->areg[2] = res;
	do_syscall_trace();
}
