/*
 * Copyright (C) 2005 MIPS Technologies, Inc.  All rights reserved.
 *
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License (Version 2) as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/unistd.h>
#include <linux/file.h>
#include <linux/fdtable.h>
#include <linux/fs.h>
#include <linux/syscalls.h>
#include <linux/workqueue.h>
#include <linux/errno.h>
#include <linux/list.h>

#include <asm/vpe.h>
#include <asm/rtlx.h>
#include <asm/kspd.h>

static struct workqueue_struct *workqueue;
static struct work_struct work;

extern unsigned long cpu_khz;

struct mtsp_syscall {
	int cmd;
	unsigned char abi;
	unsigned char size;
};

struct mtsp_syscall_ret {
	int retval;
	int errno;
};

struct mtsp_syscall_generic {
	int arg0;
	int arg1;
	int arg2;
	int arg3;
	int arg4;
	int arg5;
	int arg6;
};

static struct list_head kspd_notifylist;
static int sp_stopping;

/* these should match with those in the SDE kit */
#define MTSP_SYSCALL_BASE	0
#define MTSP_SYSCALL_EXIT	(MTSP_SYSCALL_BASE + 0)
#define MTSP_SYSCALL_OPEN	(MTSP_SYSCALL_BASE + 1)
#define MTSP_SYSCALL_READ	(MTSP_SYSCALL_BASE + 2)
#define MTSP_SYSCALL_WRITE	(MTSP_SYSCALL_BASE + 3)
#define MTSP_SYSCALL_CLOSE	(MTSP_SYSCALL_BASE + 4)
#define MTSP_SYSCALL_LSEEK32	(MTSP_SYSCALL_BASE + 5)
#define MTSP_SYSCALL_ISATTY	(MTSP_SYSCALL_BASE + 6)
#define MTSP_SYSCALL_GETTIME	(MTSP_SYSCALL_BASE + 7)
#define MTSP_SYSCALL_PIPEFREQ	(MTSP_SYSCALL_BASE + 8)
#define MTSP_SYSCALL_GETTOD	(MTSP_SYSCALL_BASE + 9)
#define MTSP_SYSCALL_IOCTL     (MTSP_SYSCALL_BASE + 10)

#define MTSP_O_RDONLY		0x0000
#define MTSP_O_WRONLY		0x0001
#define MTSP_O_RDWR		0x0002
#define MTSP_O_NONBLOCK		0x0004
#define MTSP_O_APPEND		0x0008
#define MTSP_O_SHLOCK		0x0010
#define MTSP_O_EXLOCK		0x0020
#define MTSP_O_ASYNC		0x0040
#define MTSP_O_FSYNC		O_SYNC
#define MTSP_O_NOFOLLOW		0x0100
#define MTSP_O_SYNC		0x0080
#define MTSP_O_CREAT		0x0200
#define MTSP_O_TRUNC		0x0400
#define MTSP_O_EXCL		0x0800
#define MTSP_O_BINARY		0x8000

extern int tclimit;

struct apsp_table  {
	int sp;
	int ap;
};

/* we might want to do the mode flags too */
struct apsp_table open_flags_table[] = {
	{ MTSP_O_RDWR, O_RDWR },
	{ MTSP_O_WRONLY, O_WRONLY },
	{ MTSP_O_CREAT, O_CREAT },
	{ MTSP_O_TRUNC, O_TRUNC },
	{ MTSP_O_NONBLOCK, O_NONBLOCK },
	{ MTSP_O_APPEND, O_APPEND },
	{ MTSP_O_NOFOLLOW, O_NOFOLLOW }
};

struct apsp_table syscall_command_table[] = {
	{ MTSP_SYSCALL_OPEN, __NR_open },
	{ MTSP_SYSCALL_CLOSE, __NR_close },
	{ MTSP_SYSCALL_READ, __NR_read },
	{ MTSP_SYSCALL_WRITE, __NR_write },
	{ MTSP_SYSCALL_LSEEK32, __NR_lseek },
	{ MTSP_SYSCALL_IOCTL, __NR_ioctl }
};

static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3)
{
	register long int _num  __asm__("$2") = num;
	register long int _arg0  __asm__("$4") = arg0;
	register long int _arg1  __asm__("$5") = arg1;
	register long int _arg2  __asm__("$6") = arg2;
	register long int _arg3  __asm__("$7") = arg3;

	mm_segment_t old_fs;

	old_fs = get_fs();
 	set_fs(KERNEL_DS);

  	__asm__ __volatile__ (
 	"	syscall					\n"
 	: "=r" (_num), "=r" (_arg3)
 	: "r" (_num), "r" (_arg0), "r" (_arg1), "r" (_arg2), "r" (_arg3));

	set_fs(old_fs);

	/* $a3 is error flag */
	if (_arg3)
		return -_num;

	return _num;
}

static int translate_syscall_command(int cmd)
{
	int i;
	int ret = -1;

	for (i = 0; i < ARRAY_SIZE(syscall_command_table); i++) {
		if ((cmd == syscall_command_table[i].sp))
			return syscall_command_table[i].ap;
	}

	return ret;
}

static unsigned int translate_open_flags(int flags)
{
	int i;
	unsigned int ret = 0;

	for (i = 0; i < ARRAY_SIZE(open_flags_table); i++) {
		if( (flags & open_flags_table[i].sp) ) {
			ret |= open_flags_table[i].ap;
		}
	}

	return ret;
}


static void sp_setfsuidgid( uid_t uid, gid_t gid)
{
	current->cred->fsuid = uid;
	current->cred->fsgid = gid;

	key_fsuid_changed(current);
	key_fsgid_changed(current);
}

/*
 * Expects a request to be on the sysio channel. Reads it.  Decides whether
 * its a linux syscall and runs it, or whatever.  Puts the return code back
 * into the request and sends the whole thing back.
 */
void sp_work_handle_request(void)
{
	struct mtsp_syscall sc;
	struct mtsp_syscall_generic generic;
	struct mtsp_syscall_ret ret;
	struct kspd_notifications *n;
	unsigned long written;
	mm_segment_t old_fs;
	struct timeval tv;
	struct timezone tz;
	int cmd;

	char *vcwd;
	int size;

	ret.retval = -1;

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall))) {
		set_fs(old_fs);
		printk(KERN_ERR "Expected request but nothing to read\n");
		return;
	}

	size = sc.size;

	if (size) {
		if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size)) {
			set_fs(old_fs);
			printk(KERN_ERR "Expected request but nothing to read\n");
			return;
		}
	}

	/* Run the syscall at the privilege of the user who loaded the
	   SP program */

	if (vpe_getuid(tclimit))
		sp_setfsuidgid(vpe_getuid(tclimit), vpe_getgid(tclimit));

	switch (sc.cmd) {
	/* needs the flags argument translating from SDE kit to
	   linux */
 	case MTSP_SYSCALL_PIPEFREQ:
 		ret.retval = cpu_khz * 1000;
 		ret.errno = 0;
 		break;

 	case MTSP_SYSCALL_GETTOD:
 		memset(&tz, 0, sizeof(tz));
 		if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv,
					     (int)&tz, 0, 0)) == 0)
		ret.retval = tv.tv_sec;
		break;

 	case MTSP_SYSCALL_EXIT:
		list_for_each_entry(n, &kspd_notifylist, list)
			n->kspd_sp_exit(tclimit);
		sp_stopping = 1;

		printk(KERN_DEBUG "KSPD got exit syscall from SP exitcode %d\n",
		       generic.arg0);
 		break;

 	case MTSP_SYSCALL_OPEN:
 		generic.arg1 = translate_open_flags(generic.arg1);

		vcwd = vpe_getcwd(tclimit);

		/* change to cwd of the process that loaded the SP program */
		old_fs = get_fs();
		set_fs(KERNEL_DS);
		sys_chdir(vcwd);
		set_fs(old_fs);

 		sc.cmd = __NR_open;

		/* fall through */

  	default:
 		if ((sc.cmd >= __NR_Linux) &&
		    (sc.cmd <= (__NR_Linux +  __NR_Linux_syscalls)) )
			cmd = sc.cmd;
		else
			cmd = translate_syscall_command(sc.cmd);

		if (cmd >= 0) {
			ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1,
			                        generic.arg2, generic.arg3);
		} else
 			printk(KERN_WARNING
			       "KSPD: Unknown SP syscall number %d\n", sc.cmd);
		break;
 	} /* switch */

	if (vpe_getuid(tclimit))
		sp_setfsuidgid( 0, 0);

	old_fs = get_fs();
	set_fs(KERNEL_DS);
	written = rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(ret));
	set_fs(old_fs);
	if (written < sizeof(ret))
		printk("KSPD: sp_work_handle_request failed to send to SP\n");
}

static void sp_cleanup(void)
{
	struct files_struct *files = current->files;
	int i, j;
	struct fdtable *fdt;

	j = 0;

	/*
	 * It is safe to dereference the fd table without RCU or
	 * ->file_lock
	 */
	fdt = files_fdtable(files);
	for (;;) {
		unsigned long set;
		i = j * __NFDBITS;
		if (i >= fdt->max_fds)
			break;
		set = fdt->open_fds->fds_bits[j++];
		while (set) {
			if (set & 1) {
				struct file * file = xchg(&fdt->fd[i], NULL);
				if (file)
					filp_close(file, files);
			}
			i++;
			set >>= 1;
		}
	}

	/* Put daemon cwd back to root to avoid umount problems */
	sys_chdir("/");
}

static int channel_open;

/* the work handler */
static void sp_work(struct work_struct *unused)
{
	if (!channel_open) {
		if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) {
			printk("KSPD: unable to open sp channel\n");
			sp_stopping = 1;
		} else {
			channel_open++;
			printk(KERN_DEBUG "KSPD: SP channel opened\n");
		}
	} else {
		/* wait for some data, allow it to sleep */
		rtlx_read_poll(RTLX_CHANNEL_SYSIO, 1);

		/* Check we haven't been woken because we are stopping */
		if (!sp_stopping)
			sp_work_handle_request();
	}

	if (!sp_stopping)
		queue_work(workqueue, &work);
	else
		sp_cleanup();
}

static void startwork(int vpe)
{
	sp_stopping = channel_open = 0;

	if (workqueue == NULL) {
		if ((workqueue = create_singlethread_workqueue("kspd")) == NULL) {
			printk(KERN_ERR "unable to start kspd\n");
			return;
		}

		INIT_WORK(&work, sp_work);
	}

	queue_work(workqueue, &work);
}

static void stopwork(int vpe)
{
	sp_stopping = 1;

	printk(KERN_DEBUG "KSPD: SP stopping\n");
}

void kspd_notify(struct kspd_notifications *notify)
{
	list_add(&notify->list, &kspd_notifylist);
}

static struct vpe_notifications notify;
static int kspd_module_init(void)
{
	INIT_LIST_HEAD(&kspd_notifylist);

	notify.start = startwork;
	notify.stop = stopwork;
	vpe_notify(tclimit, &notify);

	return 0;
}

static void kspd_module_exit(void)
{

}

module_init(kspd_module_init);
module_exit(kspd_module_exit);

MODULE_DESCRIPTION("MIPS KSPD");
MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
MODULE_LICENSE("GPL");
