/*
 * 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/config.h>
#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>
#include <asm/ipc.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_mmap2(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();
}
