/*
 * Copyright (C) 2003, Axis Communications AB.
 */

#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/syscalls.h>
#include <linux/vmalloc.h>

#include <asm/io.h>
#include <asm/processor.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/arch/ptrace.h>
#include <asm/arch/hwregs/cpu_vect.h>

extern unsigned long cris_signal_return_page;

/* Flag to check if a signal is blockable. */
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))

/*
 * A syscall in CRIS is really a "break 13" instruction, which is 2
 * bytes. The registers is manipulated so upon return the instruction
 * will be executed again.
 *
 * This relies on that PC points to the instruction after the break call.
 */
#define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->erp -= 2;

/* Signal frames. */
struct signal_frame {
	struct sigcontext sc;
	unsigned long extramask[_NSIG_WORDS - 1];
	unsigned char retcode[8];	/* Trampoline code. */
};

struct rt_signal_frame {
	struct siginfo *pinfo;
	void *puc;
	struct siginfo info;
	struct ucontext uc;
	unsigned char retcode[8];	/* Trampoline code. */
};

void do_signal(int restart, struct pt_regs *regs);
void keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
		      struct pt_regs *regs);
/*
 * Swap in the new signal mask, and wait for a signal. Define some
 * dummy arguments to be able to reach the regs argument.
 */
int
sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
	       long srp, struct pt_regs *regs)
{
	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
	current->state = TASK_INTERRUPTIBLE;
	schedule();
	set_thread_flag(TIF_RESTORE_SIGMASK);
	return -ERESTARTNOHAND;
}

int
sys_sigaction(int signal, const struct old_sigaction *act,
	      struct old_sigaction *oact)
{
	int retval;
	struct k_sigaction newk;
	struct k_sigaction oldk;

	if (act) {
		old_sigset_t mask;

		if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
		    __get_user(newk.sa.sa_handler, &act->sa_handler) ||
		    __get_user(newk.sa.sa_restorer, &act->sa_restorer))
			return -EFAULT;

		__get_user(newk.sa.sa_flags, &act->sa_flags);
		__get_user(mask, &act->sa_mask);
		siginitset(&newk.sa.sa_mask, mask);
	}

	retval = do_sigaction(signal, act ? &newk : NULL, oact ? &oldk : NULL);

	if (!retval && oact) {
		if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
		    __put_user(oldk.sa.sa_handler, &oact->sa_handler) ||
		    __put_user(oldk.sa.sa_restorer, &oact->sa_restorer))
			return -EFAULT;

		__put_user(oldk.sa.sa_flags, &oact->sa_flags);
		__put_user(oldk.sa.sa_mask.sig[0], &oact->sa_mask);
	}

	return retval;
}

int
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
{
	return do_sigaltstack(uss, uoss, rdusp());
}

static int
restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
{
	unsigned int err = 0;
	unsigned long old_usp;

        /* Always make any pending restarted system calls return -EINTR */
	current_thread_info()->restart_block.fn = do_no_restart_syscall;

	/*
	 * Restore the registers from &sc->regs. sc is already checked
	 * for VERIFY_READ since the signal_frame was previously
	 * checked in sys_sigreturn().
	 */
	if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
		goto badframe;

	/* Make that the user-mode flag is set. */
	regs->ccs |= (1 << (U_CCS_BITNR + CCS_SHIFT));

	/* Restore the old USP. */
	err |= __get_user(old_usp, &sc->usp);
	wrusp(old_usp);

	return err;

badframe:
	return 1;
}

/* Define some dummy arguments to be able to reach the regs argument. */
asmlinkage int
sys_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
	      struct pt_regs *regs)
{
	sigset_t set;
	struct signal_frame __user *frame;
	unsigned long oldspc = regs->spc;
	unsigned long oldccs = regs->ccs;

	frame = (struct signal_frame *) rdusp();

	/*
	 * Since the signal is stacked on a dword boundary, the frame
	 * should be dword aligned here as well. It it's not, then the
	 * user is trying some funny business.
	 */
	if (((long)frame) & 3)
		goto badframe;

	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
		goto badframe;

	if (__get_user(set.sig[0], &frame->sc.oldmask) ||
	    (_NSIG_WORDS > 1 && __copy_from_user(&set.sig[1],
						 frame->extramask,
						 sizeof(frame->extramask))))
		goto badframe;

	sigdelsetmask(&set, ~_BLOCKABLE);
	spin_lock_irq(&current->sighand->siglock);

	current->blocked = set;

	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	if (restore_sigcontext(regs, &frame->sc))
		goto badframe;

	keep_debug_flags(oldccs, oldspc, regs);

	return regs->r10;

badframe:
	force_sig(SIGSEGV, current);
	return 0;
}

/* Define some dummy variables to be able to reach the regs argument. */
asmlinkage int
sys_rt_sigreturn(long r10, long r11, long r12, long r13, long mof, long srp,
		 struct pt_regs *regs)
{
	sigset_t set;
	struct rt_signal_frame __user *frame;
	unsigned long oldspc = regs->spc;
	unsigned long oldccs = regs->ccs;

	frame = (struct rt_signal_frame *) rdusp();

	/*
	 * Since the signal is stacked on a dword boundary, the frame
	 * should be dword aligned here as well. It it's not, then the
	 * user is trying some funny business.
	 */
	if (((long)frame) & 3)
		goto badframe;

	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
		goto badframe;

	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
		goto badframe;

	sigdelsetmask(&set, ~_BLOCKABLE);
	spin_lock_irq(&current->sighand->siglock);

	current->blocked = set;

	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
		goto badframe;

	if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT)
		goto badframe;

	keep_debug_flags(oldccs, oldspc, regs);

	return regs->r10;

badframe:
	force_sig(SIGSEGV, current);
	return 0;
}

/* Setup a signal frame. */
static int
setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
		 unsigned long mask)
{
	int err;
	unsigned long usp;

	err = 0;
	usp = rdusp();

	/*
	 * Copy the registers. They are located first in sc, so it's
	 * possible to use sc directly.
	 */
	err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));

	err |= __put_user(mask, &sc->oldmask);
	err |= __put_user(usp, &sc->usp);

	return err;
}

/* Figure out where to put the new signal frame - usually on the stack. */
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{
	unsigned long sp;

	sp = rdusp();

	/* This is the X/Open sanctioned signal stack switching. */
	if (ka->sa.sa_flags & SA_ONSTACK) {
		if (!on_sig_stack(sp))
			sp = current->sas_ss_sp + current->sas_ss_size;
	}

	/* Make sure the frame is dword-aligned. */
	sp &= ~3;

	return (void __user *)(sp - frame_size);
}

/* Grab and setup a signal frame.
 *
 * Basically a lot of state-info is stacked, and arranged for the
 * user-mode program to return to the kernel using either a trampiline
 * which performs the syscall sigreturn(), or a provided user-mode
 * trampoline.
  */
static int
setup_frame(int sig, struct k_sigaction *ka,  sigset_t *set,
	    struct pt_regs * regs)
{
	int err;
	unsigned long return_ip;
	struct signal_frame __user *frame;

	err = 0;
	frame = get_sigframe(ka, regs, sizeof(*frame));

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		goto give_sigsegv;

	err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);

	if (err)
		goto give_sigsegv;

	if (_NSIG_WORDS > 1) {
		err |= __copy_to_user(frame->extramask, &set->sig[1],
				      sizeof(frame->extramask));
	}

	if (err)
		goto give_sigsegv;

	/*
	 * Set up to return from user-space. If provided, use a stub
	 * already located in user-space.
	 */
	if (ka->sa.sa_flags & SA_RESTORER) {
		return_ip = (unsigned long)ka->sa.sa_restorer;
	} else {
		/* Trampoline - the desired return ip is in the signal return page. */
		return_ip = cris_signal_return_page;

		/*
		 * This is movu.w __NR_sigreturn, r9; break 13;
		 *
		 * WE DO NOT USE IT ANY MORE! It's only left here for historical
		 * reasons and because gdb uses it as a signature to notice
		 * signal handler stack frames.
		 */
		err |= __put_user(0x9c5f,         (short __user*)(frame->retcode+0));
		err |= __put_user(__NR_sigreturn, (short __user*)(frame->retcode+2));
		err |= __put_user(0xe93d,         (short __user*)(frame->retcode+4));
	}

	if (err)
		goto give_sigsegv;

	/*
	 * Set up registers for signal handler.
	 *
	 * Where the code enters now.
	 * Where the code enter later.
	 * First argument, signo.
	 */
	regs->erp = (unsigned long) ka->sa.sa_handler;
	regs->srp = return_ip;
	regs->r10 = sig;

	/* Actually move the USP to reflect the stacked frame. */
	wrusp((unsigned long)frame);

	return 0;

give_sigsegv:
	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;

	force_sig(SIGSEGV, current);
	return -EFAULT;
}

static int
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
	       sigset_t *set, struct pt_regs * regs)
{
	int err;
	unsigned long return_ip;
	struct rt_signal_frame __user *frame;

	err = 0;
	frame = get_sigframe(ka, regs, sizeof(*frame));

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
		goto give_sigsegv;

	/* TODO: what is the current->exec_domain stuff and invmap ? */

	err |= __put_user(&frame->info, &frame->pinfo);
	err |= __put_user(&frame->uc, &frame->puc);
	err |= copy_siginfo_to_user(&frame->info, info);

	if (err)
		goto give_sigsegv;

	/* Clear all the bits of the ucontext we don't use.  */
	err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
	err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));

	if (err)
		goto give_sigsegv;

	/*
	 * Set up to return from user-space. If provided, use a stub
	 * already located in user-space.
	 */
	if (ka->sa.sa_flags & SA_RESTORER) {
		return_ip = (unsigned long) ka->sa.sa_restorer;
	} else {
		/* Trampoline - the desired return ip is in the signal return page. */
		return_ip = cris_signal_return_page + 6;

		/*
		 * This is movu.w __NR_rt_sigreturn, r9; break 13;
		 *
		 * WE DO NOT USE IT ANY MORE! It's only left here for historical
		 * reasons and because gdb uses it as a signature to notice
		 * signal handler stack frames.
		 */
		err |= __put_user(0x9c5f, (short __user*)(frame->retcode+0));

		err |= __put_user(__NR_rt_sigreturn,
				  (short __user*)(frame->retcode+2));

		err |= __put_user(0xe93d, (short __user*)(frame->retcode+4));
	}

	if (err)
		goto give_sigsegv;

	/*
	 * Set up registers for signal handler.
	 *
	 * Where the code enters now.
	 * Where the code enters later.
	 * First argument is signo.
	 * Second argument is (siginfo_t *).
	 * Third argument is unused.
	 */
	regs->erp = (unsigned long) ka->sa.sa_handler;
	regs->srp = return_ip;
	regs->r10 = sig;
	regs->r11 = (unsigned long) &frame->info;
	regs->r12 = 0;

	/* Actually move the usp to reflect the stacked frame. */
	wrusp((unsigned long)frame);

	return 0;

give_sigsegv:
	if (sig == SIGSEGV)
		ka->sa.sa_handler = SIG_DFL;

	force_sig(SIGSEGV, current);
	return -EFAULT;
}

/* Invoke a singal handler to, well, handle the signal. */
static inline int
handle_signal(int canrestart, unsigned long sig,
	      siginfo_t *info, struct k_sigaction *ka,
              sigset_t *oldset, struct pt_regs * regs)
{
	int ret;

	/* Check if this got called from a system call. */
	if (canrestart) {
		/* If so, check system call restarting. */
		switch (regs->r10) {
			case -ERESTART_RESTARTBLOCK:
			case -ERESTARTNOHAND:
				/*
				 * This means that the syscall should
				 * only be restarted if there was no
				 * handler for the signal, and since
				 * this point isn't reached unless
				 * there is a handler, there's no need
				 * to restart.
				 */
				regs->r10 = -EINTR;
				break;

                        case -ERESTARTSYS:
				/*
				 * This means restart the syscall if
                                 * there is no handler, or the handler
                                 * was registered with SA_RESTART.
				 */
				if (!(ka->sa.sa_flags & SA_RESTART)) {
					regs->r10 = -EINTR;
					break;
				}

				/* Fall through. */

			case -ERESTARTNOINTR:
				/*
				 * This means that the syscall should
                                 * be called again after the signal
                                 * handler returns.
				 */
				RESTART_CRIS_SYS(regs);
				break;
                }
        }

	/* Set up the stack frame. */
	if (ka->sa.sa_flags & SA_SIGINFO)
		ret = setup_rt_frame(sig, ka, info, oldset, regs);
	else
		ret = setup_frame(sig, ka, oldset, regs);

	if (ka->sa.sa_flags & SA_ONESHOT)
		ka->sa.sa_handler = SIG_DFL;

	if (ret == 0) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked, &current->blocked,
			&ka->sa.sa_mask);
		if (!(ka->sa.sa_flags & SA_NODEFER))
			sigaddset(&current->blocked, sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);
	}

	return ret;
}

/*
 * Note that 'init' is a special process: it doesn't get signals it doesn't
 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 * mistake.
 *
 * Also note that the regs structure given here as an argument, is the latest
 * pushed pt_regs. It may or may not be the same as the first pushed registers
 * when the initial usermode->kernelmode transition took place. Therefore
 * we can use user_mode(regs) to see if we came directly from kernel or user
 * mode below.
 */
void
do_signal(int canrestart, struct pt_regs *regs)
{
	int signr;
	siginfo_t info;
        struct k_sigaction ka;
	sigset_t *oldset;

	/*
	 * The common case should go fast, which is why this point is
	 * reached from kernel-mode. If that's the case, just return
	 * without doing anything.
	 */
	if (!user_mode(regs))
		return;

	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	signr = get_signal_to_deliver(&info, &ka, regs, NULL);

	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		if (handle_signal(canrestart, signr, &info, &ka,
				oldset, regs)) {
			/* a signal was successfully delivered; the saved
			 * sigmask will have been stored in the signal frame,
			 * and will be restored by sigreturn, so we can simply
			 * clear the TIF_RESTORE_SIGMASK flag */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);
		}

		return;
	}

	/* Got here from a system call? */
	if (canrestart) {
		/* Restart the system call - no handlers present. */
		if (regs->r10 == -ERESTARTNOHAND ||
		    regs->r10 == -ERESTARTSYS ||
		    regs->r10 == -ERESTARTNOINTR) {
			RESTART_CRIS_SYS(regs);
		}

		if (regs->r10 == -ERESTART_RESTARTBLOCK){
			regs->r10 = __NR_restart_syscall;
			regs->erp -= 2;
		}
	}

	/* if there's no signal to deliver, we just put the saved sigmask
	 * back */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}
}

asmlinkage void
ugdb_trap_user(struct thread_info *ti, int sig)
{
	if (((user_regs(ti)->exs & 0xff00) >> 8) != SINGLE_STEP_INTR_VECT) {
		/* Zero single-step PC if the reason we stopped wasn't a single
		   step exception. This is to avoid relying on it when it isn't
		   reliable. */
		user_regs(ti)->spc = 0;
	}
	/* FIXME: Filter out false h/w breakpoint hits (i.e. EDA
	   not withing any configured h/w breakpoint range). Synchronize with
	   what already exists for kernel debugging.  */
	if (((user_regs(ti)->exs & 0xff00) >> 8) == BREAK_8_INTR_VECT) {
		/* Break 8: subtract 2 from ERP unless in a delay slot. */
		if (!(user_regs(ti)->erp & 0x1))
			user_regs(ti)->erp -= 2;
	}
	sys_kill(ti->task->pid, sig);
}

void
keep_debug_flags(unsigned long oldccs, unsigned long oldspc,
		 struct pt_regs *regs)
{
	if (oldccs & (1 << Q_CCS_BITNR)) {
		/* Pending single step due to single-stepping the break 13
		   in the signal trampoline: keep the Q flag. */
		regs->ccs |= (1 << Q_CCS_BITNR);
		/* S flag should be set - complain if it's not. */
		if (!(oldccs & (1 << (S_CCS_BITNR + CCS_SHIFT)))) {
			printk("Q flag but no S flag?");
		}
		regs->ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
		/* Assume the SPC is valid and interesting. */
		regs->spc = oldspc;

	} else if (oldccs & (1 << (S_CCS_BITNR + CCS_SHIFT))) {
		/* If a h/w bp was set in the signal handler we need
		   to keep the S flag. */
		regs->ccs |= (1 << (S_CCS_BITNR + CCS_SHIFT));
		/* Don't keep the old SPC though; if we got here due to
		   a single-step, the Q flag should have been set. */
	} else if (regs->spc) {
		/* If we were single-stepping *before* the signal was taken,
		   we don't want to restore that state now, because GDB will
		   have forgotten all about it. */
		regs->spc = 0;
		regs->ccs &= ~(1 << (S_CCS_BITNR + CCS_SHIFT));
	}
}

/* Set up the trampolines on the signal return page. */
int __init
cris_init_signal(void)
{
	u16* data = kmalloc(PAGE_SIZE, GFP_KERNEL);

	/* This is movu.w __NR_sigreturn, r9; break 13; */
	data[0] = 0x9c5f;
	data[1] = __NR_sigreturn;
	data[2] = 0xe93d;
	/* This is movu.w __NR_rt_sigreturn, r9; break 13; */
	data[3] = 0x9c5f;
	data[4] = __NR_rt_sigreturn;
	data[5] = 0xe93d;

	/* Map to userspace with appropriate permissions (no write access...) */
	cris_signal_return_page = (unsigned long)
          __ioremap_prot(virt_to_phys(data), PAGE_SIZE, PAGE_SIGNAL_TRAMPOLINE);

	return 0;
}

__initcall(cris_init_signal);
