/*
 *  Copyright (C) 2000-2003  Axis Communications AB
 *
 *  Authors:   Bjorn Wesen (bjornw@axis.com)
 *             Mikael Starvik (starvik@axis.com)
 *             Tobias Anderberg (tobiasa@axis.com), CRISv32 port.
 *
 * This file handles the architecture-dependent parts of process handling..
 */

#include <linux/sched.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <asm/arch/hwregs/reg_rdwr.h>
#include <asm/arch/hwregs/reg_map.h>
#include <asm/arch/hwregs/timer_defs.h>
#include <asm/arch/hwregs/intr_vect_defs.h>

extern void stop_watchdog(void);

#ifdef CONFIG_ETRAX_GPIO
extern void etrax_gpio_wake_up_check(void); /* Defined in drivers/gpio.c. */
#endif

extern int cris_hlt_counter;

/* We use this if we don't have any better idle routine. */
void default_idle(void)
{
	local_irq_disable();
	if (!need_resched() && !cris_hlt_counter) {
	        /* Halt until exception. */
		__asm__ volatile("ei    \n\t"
                                 "halt      ");
	}
	local_irq_enable();
}

/*
 * Free current thread data structures etc..
 */

extern void deconfigure_bp(long pid);
void exit_thread(void)
{
	deconfigure_bp(current->pid);
}

/*
 * If the watchdog is enabled, disable interrupts and enter an infinite loop.
 * The watchdog will reset the CPU after 0.1s. If the watchdog isn't enabled
 * then enable it and wait.
 */
extern void arch_enable_nmi(void);

void
hard_reset_now(void)
{
	/*
	 * Don't declare this variable elsewhere.  We don't want any other
	 * code to know about it than the watchdog handler in entry.S and
	 * this code, implementing hard reset through the watchdog.
	 */
#if defined(CONFIG_ETRAX_WATCHDOG)
	extern int cause_of_death;
#endif

	printk("*** HARD RESET ***\n");
	local_irq_disable();

#if defined(CONFIG_ETRAX_WATCHDOG)
	cause_of_death = 0xbedead;
#else
{
	reg_timer_rw_wd_ctrl wd_ctrl = {0};

	stop_watchdog();

	wd_ctrl.key = 16;	/* Arbitrary key. */
	wd_ctrl.cnt = 1;	/* Minimum time. */
	wd_ctrl.cmd = regk_timer_start;

        arch_enable_nmi();
	REG_WR(timer, regi_timer, rw_wd_ctrl, wd_ctrl);
}
#endif

	while (1)
		; /* Wait for reset. */
}

/*
 * Return saved PC of a blocked thread.
 */
unsigned long thread_saved_pc(struct task_struct *t)
{
	return task_pt_regs(t)->erp;
}

static void
kernel_thread_helper(void* dummy, int (*fn)(void *), void * arg)
{
	fn(arg);
	do_exit(-1); /* Should never be called, return bad exit value. */
}

/* Create a kernel thread. */
int
kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
	struct pt_regs regs;

	memset(&regs, 0, sizeof(regs));

        /* Don't use r10 since that is set to 0 in copy_thread. */
	regs.r11 = (unsigned long) fn;
	regs.r12 = (unsigned long) arg;
	regs.erp = (unsigned long) kernel_thread_helper;
	regs.ccs = 1 << (I_CCS_BITNR + CCS_SHIFT);

	/* Create the new process. */
        return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
}

/*
 * Setup the child's kernel stack with a pt_regs and call switch_stack() on it.
 * It will be unnested during _resume and _ret_from_sys_call when the new thread
 * is scheduled.
 *
 * Also setup the thread switching structure which is used to keep
 * thread-specific data during _resumes.
 */

extern asmlinkage void ret_from_fork(void);

int
copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
	unsigned long unused,
	struct task_struct *p, struct pt_regs *regs)
{
	struct pt_regs *childregs;
	struct switch_stack *swstack;

	/*
	 * Put the pt_regs structure at the end of the new kernel stack page and
	 * fix it up. Note: the task_struct doubles as the kernel stack for the
	 * task.
	 */
	childregs = task_pt_regs(p);
	*childregs = *regs;	/* Struct copy of pt_regs. */
        p->set_child_tid = p->clear_child_tid = NULL;
        childregs->r10 = 0;	/* Child returns 0 after a fork/clone. */

	/* Set a new TLS ?
	 * The TLS is in $mof beacuse it is the 5th argument to sys_clone.
	 */
	if (p->mm && (clone_flags & CLONE_SETTLS)) {
		task_thread_info(p)->tls = regs->mof;
	}

	/* Put the switch stack right below the pt_regs. */
	swstack = ((struct switch_stack *) childregs) - 1;

	/* Paramater to ret_from_sys_call. 0 is don't restart the syscall. */
	swstack->r9 = 0;

	/*
	 * We want to return into ret_from_sys_call after the _resume.
	 * ret_from_fork will call ret_from_sys_call.
	 */
	swstack->return_ip = (unsigned long) ret_from_fork;

	/* Fix the user-mode and kernel-mode stackpointer. */
	p->thread.usp = usp;
	p->thread.ksp = (unsigned long) swstack;

	return 0;
}

/*
 * Be aware of the "magic" 7th argument in the four system-calls below.
 * They need the latest stackframe, which is put as the 7th argument by
 * entry.S. The previous arguments are dummies or actually used, but need
 * to be defined to reach the 7th argument.
 *
 * N.B.: Another method to get the stackframe is to use current_regs(). But
 * it returns the latest stack-frame stacked when going from _user mode_ and
 * some of these (at least sys_clone) are called from kernel-mode sometimes
 * (for example during kernel_thread, above) and thus cannot use it. Thus,
 * to be sure not to get any surprises, we use the method for the other calls
 * as well.
 */
asmlinkage int
sys_fork(long r10, long r11, long r12, long r13, long mof, long srp,
	struct pt_regs *regs)
{
	return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
}

/* FIXME: Is parent_tid/child_tid really third/fourth argument? Update lib? */
asmlinkage int
sys_clone(unsigned long newusp, unsigned long flags, int *parent_tid, int *child_tid,
	unsigned long tls, long srp, struct pt_regs *regs)
{
	if (!newusp)
		newusp = rdusp();

	return do_fork(flags, newusp, regs, 0, parent_tid, child_tid);
}

/*
 * vfork is a system call in i386 because of register-pressure - maybe
 * we can remove it and handle it in libc but we put it here until then.
 */
asmlinkage int
sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
	struct pt_regs *regs)
{
	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
}

/* sys_execve() executes a new program. */
asmlinkage int
sys_execve(const char *fname, char **argv, char **envp, long r13, long mof, long srp,
	struct pt_regs *regs)
{
	int error;
	char *filename;

	filename = getname(fname);
	error = PTR_ERR(filename);

	if (IS_ERR(filename))
	        goto out;

	error = do_execve(filename, argv, envp, regs);
	putname(filename);
 out:
	return error;
}

unsigned long
get_wchan(struct task_struct *p)
{
	/* TODO */
	return 0;
}
#undef last_sched
#undef first_sched

void show_regs(struct pt_regs * regs)
{
	unsigned long usp = rdusp();
        printk("ERP: %08lx SRP: %08lx  CCS: %08lx USP: %08lx MOF: %08lx\n",
		regs->erp, regs->srp, regs->ccs, usp, regs->mof);

	printk(" r0: %08lx  r1: %08lx   r2: %08lx  r3: %08lx\n",
		regs->r0, regs->r1, regs->r2, regs->r3);

	printk(" r4: %08lx  r5: %08lx   r6: %08lx  r7: %08lx\n",
		regs->r4, regs->r5, regs->r6, regs->r7);

	printk(" r8: %08lx  r9: %08lx  r10: %08lx r11: %08lx\n",
		regs->r8, regs->r9, regs->r10, regs->r11);

	printk("r12: %08lx r13: %08lx oR10: %08lx\n",
		regs->r12, regs->r13, regs->orig_r10);
}
