/*
 * 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/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 = NULL;
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 = 0;

/* 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 < (sizeof(open_flags_table) / sizeof(struct apsp_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->fsuid = uid;
	current->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 priviledge 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 the 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;
		}
	}
}

static int channel_open = 0;

/* 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");
