/*
 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu>
 * Copyright (C) 2007-2009 PetaLogix
 * Copyright (C) 2007 John Williams <john.williams@petalogix.com>
 *
 * Copyright (C) 2006 Atmark Techno, Inc.
 *	Yasushi SHOJI <yashi@atmark-techno.com>
 *	Tetsuya OHKAWA <tetsuya@atmark-techno.com>
 *
 * 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.
 */

#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/stat.h>
#include <linux/mman.h>
#include <linux/sys.h>
#include <linux/ipc.h>
#include <linux/utsname.h>
#include <linux/file.h>
#include <linux/module.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/unistd.h>

#include <asm/syscalls.h>
/*
 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
 *
 * This is really horribly ugly. This will be remove with new toolchain.
 */
asmlinkage int
sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth)
{
	int version, ret;

	version = call >> 16; /* hack for backward compatibility */
	call &= 0xffff;

	ret = -EINVAL;
	switch (call) {
	case SEMOP:
		ret = sys_semop(first, (struct sembuf *)ptr, second);
		break;
	case SEMGET:
		ret = sys_semget(first, second, third);
		break;
	case SEMCTL:
	{
		union semun fourth;

		if (!ptr)
			break;
		ret = (access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT)
				|| (get_user(fourth.__pad, (void **)ptr)) ;
		if (ret)
			break;
		ret = sys_semctl(first, second, third, fourth);
		break;
	}
	case MSGSND:
		ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third);
		break;
	case MSGRCV:
		switch (version) {
		case 0: {
			struct ipc_kludge tmp;

			if (!ptr)
				break;
			ret = (access_ok(VERIFY_READ, ptr, sizeof(tmp))
				? 0 : -EFAULT) || copy_from_user(&tmp,
				(struct ipc_kludge *) ptr, sizeof(tmp));
			if (ret)
				break;
			ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp,
					third);
			break;
			}
		default:
			ret = sys_msgrcv(first, (struct msgbuf *) ptr,
					second, fifth, third);
			break;
		}
		break;
	case MSGGET:
		ret = sys_msgget((key_t) first, second);
		break;
	case MSGCTL:
		ret = sys_msgctl(first, second, (struct msqid_ds *) ptr);
		break;
	case SHMAT:
		switch (version) {
		default: {
			ulong raddr;
			ret = access_ok(VERIFY_WRITE, (ulong *) third,
					sizeof(ulong)) ? 0 : -EFAULT;
			if (ret)
				break;
			ret = do_shmat(first, (char *) ptr, second, &raddr);
			if (ret)
				break;
			ret = put_user(raddr, (ulong *) third);
			break;
			}
		case 1:	/* iBCS2 emulator entry point */
			if (!segment_eq(get_fs(), get_ds()))
				break;
			ret = do_shmat(first, (char *) ptr, second,
					(ulong *) third);
			break;
		}
		break;
	case SHMDT:
		ret = sys_shmdt((char *)ptr);
		break;
	case SHMGET:
		ret = sys_shmget(first, second, third);
		break;
	case SHMCTL:
		ret = sys_shmctl(first, second, (struct shmid_ds *) ptr);
		break;
	}
	return ret;
}

asmlinkage int sys_vfork(struct pt_regs *regs)
{
	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1,
						regs, 0, NULL, NULL);
}

asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs)
{
	if (!stack)
		stack = regs->r1;
	return do_fork(flags, stack, regs, 0, NULL, NULL);
}

asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv,
			char __user *__user *envp, struct pt_regs *regs)
{
	int error;
	char *filename;

	filename = getname(filenamei);
	error = PTR_ERR(filename);
	if (IS_ERR(filename))
		goto out;
	error = do_execve(filename, argv, envp, regs);
	putname(filename);
out:
	return error;
}

asmlinkage unsigned long
sys_mmap2(unsigned long addr, size_t len,
	unsigned long prot, unsigned long flags,
	unsigned long fd, unsigned long pgoff)
{
	struct file *file = NULL;
	int ret = -EBADF;

	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
	if (!(flags & MAP_ANONYMOUS)) {
		file = fget(fd);
		if (!file) {
			printk(KERN_INFO "no fd in mmap\r\n");
			goto out;
		}
	}

	down_write(&current->mm->mmap_sem);
	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
	up_write(&current->mm->mmap_sem);
	if (file)
		fput(file);
out:
	return ret;
}

asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
			unsigned long prot, unsigned long flags,
			unsigned long fd, off_t offset)
{
	int err = -EINVAL;

	if (offset & ~PAGE_MASK) {
		printk(KERN_INFO "no pagemask in mmap\r\n");
		goto out;
	}

	err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
out:
	return err;
}

/*
 * Do a system call from kernel instead of calling sys_execve so we
 * end up with proper pt_regs.
 */
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
	register const char *__a __asm__("r5") = filename;
	register const void *__b __asm__("r6") = argv;
	register const void *__c __asm__("r7") = envp;
	register unsigned long __syscall __asm__("r12") = __NR_execve;
	register unsigned long __ret __asm__("r3");
	__asm__ __volatile__ ("brki r14, 0x8"
			: "=r" (__ret), "=r" (__syscall)
			: "1" (__syscall), "r" (__a), "r" (__b), "r" (__c)
			: "r4", "r8", "r9",
			"r10", "r11", "r14", "cc", "memory");
	return __ret;
}
