/*
 * Copyright (C) 2004-2006 Atmel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#undef DEBUG
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/user.h>
#include <linux/security.h>
#include <linux/unistd.h>
#include <linux/notifier.h>

#include <asm/traps.h>
#include <asm/uaccess.h>
#include <asm/ocd.h>
#include <asm/mmu_context.h>
#include <linux/kdebug.h>

static struct pt_regs *get_user_regs(struct task_struct *tsk)
{
	return (struct pt_regs *)((unsigned long)task_stack_page(tsk) +
				  THREAD_SIZE - sizeof(struct pt_regs));
}

static void ptrace_single_step(struct task_struct *tsk)
{
	pr_debug("ptrace_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n",
		 tsk->pid, task_pt_regs(tsk)->pc, task_pt_regs(tsk)->sr);

	/*
	 * We can't schedule in Debug mode, so when TIF_BREAKPOINT is
	 * set, the system call or exception handler will do a
	 * breakpoint to enter monitor mode before returning to
	 * userspace.
	 *
	 * The monitor code will then notice that TIF_SINGLE_STEP is
	 * set and return to userspace with single stepping enabled.
	 * The CPU will then enter monitor mode again after exactly
	 * one instruction has been executed, and the monitor code
	 * will then send a SIGTRAP to the process.
	 */
	set_tsk_thread_flag(tsk, TIF_BREAKPOINT);
	set_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
}

/*
 * Called by kernel/ptrace.c when detaching
 *
 * Make sure any single step bits, etc. are not set
 */
void ptrace_disable(struct task_struct *child)
{
	clear_tsk_thread_flag(child, TIF_SINGLE_STEP);
	clear_tsk_thread_flag(child, TIF_BREAKPOINT);
	ocd_disable(child);
}

/*
 * Read the word at offset "offset" into the task's "struct user". We
 * actually access the pt_regs struct stored on the kernel stack.
 */
static int ptrace_read_user(struct task_struct *tsk, unsigned long offset,
			    unsigned long __user *data)
{
	unsigned long *regs;
	unsigned long value;

	if (offset & 3 || offset >= sizeof(struct user)) {
		printk("ptrace_read_user: invalid offset 0x%08lx\n", offset);
		return -EIO;
	}

	regs = (unsigned long *)get_user_regs(tsk);

	value = 0;
	if (offset < sizeof(struct pt_regs))
		value = regs[offset / sizeof(regs[0])];

	pr_debug("ptrace_read_user(%s[%u], %#lx, %p) -> %#lx\n",
		 tsk->comm, tsk->pid, offset, data, value);

	return put_user(value, data);
}

/*
 * Write the word "value" to offset "offset" into the task's "struct
 * user". We actually access the pt_regs struct stored on the kernel
 * stack.
 */
static int ptrace_write_user(struct task_struct *tsk, unsigned long offset,
			     unsigned long value)
{
	unsigned long *regs;

	pr_debug("ptrace_write_user(%s[%u], %#lx, %#lx)\n",
			tsk->comm, tsk->pid, offset, value);

	if (offset & 3 || offset >= sizeof(struct user)) {
		pr_debug("  invalid offset 0x%08lx\n", offset);
		return -EIO;
	}

	if (offset >= sizeof(struct pt_regs))
		return 0;

	regs = (unsigned long *)get_user_regs(tsk);
	regs[offset / sizeof(regs[0])] = value;

	return 0;
}

static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
{
	struct pt_regs *regs = get_user_regs(tsk);

	return copy_to_user(uregs, regs, sizeof(*regs)) ? -EFAULT : 0;
}

static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs)
{
	struct pt_regs newregs;
	int ret;

	ret = -EFAULT;
	if (copy_from_user(&newregs, uregs, sizeof(newregs)) == 0) {
		struct pt_regs *regs = get_user_regs(tsk);

		ret = -EINVAL;
		if (valid_user_regs(&newregs)) {
			*regs = newregs;
			ret = 0;
		}
	}

	return ret;
}

long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
	int ret;

	switch (request) {
	/* Read the word at location addr in the child process */
	case PTRACE_PEEKTEXT:
	case PTRACE_PEEKDATA:
		ret = generic_ptrace_peekdata(child, addr, data);
		break;

	case PTRACE_PEEKUSR:
		ret = ptrace_read_user(child, addr,
				       (unsigned long __user *)data);
		break;

	/* Write the word in data at location addr */
	case PTRACE_POKETEXT:
	case PTRACE_POKEDATA:
		ret = generic_ptrace_pokedata(child, addr, data);
		break;

	case PTRACE_POKEUSR:
		ret = ptrace_write_user(child, addr, data);
		break;

	/* continue and stop at next (return from) syscall */
	case PTRACE_SYSCALL:
	/* restart after signal */
	case PTRACE_CONT:
		ret = -EIO;
		if (!valid_signal(data))
			break;
		if (request == PTRACE_SYSCALL)
			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		else
			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		child->exit_code = data;
		/* XXX: Are we sure no breakpoints are active here? */
		wake_up_process(child);
		ret = 0;
		break;

	/*
	 * Make the child exit. Best I can do is send it a
	 * SIGKILL. Perhaps it should be put in the status that it
	 * wants to exit.
	 */
	case PTRACE_KILL:
		ret = 0;
		if (child->exit_state == EXIT_ZOMBIE)
			break;
		child->exit_code = SIGKILL;
		wake_up_process(child);
		break;

	/*
	 * execute single instruction.
	 */
	case PTRACE_SINGLESTEP:
		ret = -EIO;
		if (!valid_signal(data))
			break;
		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
		ptrace_single_step(child);
		child->exit_code = data;
		wake_up_process(child);
		ret = 0;
		break;

	case PTRACE_GETREGS:
		ret = ptrace_getregs(child, (void __user *)data);
		break;

	case PTRACE_SETREGS:
		ret = ptrace_setregs(child, (const void __user *)data);
		break;

	default:
		ret = ptrace_request(child, request, addr, data);
		break;
	}

	return ret;
}

asmlinkage void syscall_trace(void)
{
	if (!test_thread_flag(TIF_SYSCALL_TRACE))
		return;
	if (!(current->ptrace & PT_PTRACED))
		return;

	/* The 0x80 provides a way for the tracing parent to
	 * distinguish between a syscall stop and SIGTRAP delivery */
	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
				 ? 0x80 : 0));

	/*
	 * this isn't the same as continuing with a signal, but it
	 * will do for normal use.  strace only continues with a
	 * signal if the stopping signal is not SIGTRAP.  -brl
	 */
	if (current->exit_code) {
		pr_debug("syscall_trace: sending signal %d to PID %u\n",
			 current->exit_code, current->pid);
		send_sig(current->exit_code, current, 1);
		current->exit_code = 0;
	}
}

/*
 * debug_trampoline() is an assembly stub which will store all user
 * registers on the stack and execute a breakpoint instruction.
 *
 * If we single-step into an exception handler which runs with
 * interrupts disabled the whole time so it doesn't have to check for
 * pending work, its return address will be modified so that it ends
 * up returning to debug_trampoline.
 *
 * If the exception handler decides to store the user context and
 * enable interrupts after all, it will restore the original return
 * address and status register value. Before it returns, it will
 * notice that TIF_BREAKPOINT is set and execute a breakpoint
 * instruction.
 */
extern void debug_trampoline(void);

asmlinkage struct pt_regs *do_debug(struct pt_regs *regs)
{
	struct thread_info	*ti;
	unsigned long		trampoline_addr;
	u32			status;
	u32			ctrl;
	int			code;

	status = ocd_read(DS);
	ti = current_thread_info();
	code = TRAP_BRKPT;

	pr_debug("do_debug: status=0x%08x PC=0x%08lx SR=0x%08lx tif=0x%08lx\n",
			status, regs->pc, regs->sr, ti->flags);

	if (!user_mode(regs)) {
		unsigned long	die_val = DIE_BREAKPOINT;

		if (status & (1 << OCD_DS_SSS_BIT))
			die_val = DIE_SSTEP;

		if (notify_die(die_val, "ptrace", regs, 0, 0, SIGTRAP)
				== NOTIFY_STOP)
			return regs;

		if ((status & (1 << OCD_DS_SWB_BIT))
				&& test_and_clear_ti_thread_flag(
					ti, TIF_BREAKPOINT)) {
			/*
			 * Explicit breakpoint from trampoline or
			 * exception/syscall/interrupt handler.
			 *
			 * The real saved regs are on the stack right
			 * after the ones we saved on entry.
			 */
			regs++;
			pr_debug("  -> TIF_BREAKPOINT done, adjusted regs:"
					"PC=0x%08lx SR=0x%08lx\n",
					regs->pc, regs->sr);
			BUG_ON(!user_mode(regs));

			if (test_thread_flag(TIF_SINGLE_STEP)) {
				pr_debug("Going to do single step...\n");
				return regs;
			}

			/*
			 * No TIF_SINGLE_STEP means we're done
			 * stepping over a syscall. Do the trap now.
			 */
			code = TRAP_TRACE;
		} else if ((status & (1 << OCD_DS_SSS_BIT))
				&& test_ti_thread_flag(ti, TIF_SINGLE_STEP)) {

			pr_debug("Stepped into something, "
					"setting TIF_BREAKPOINT...\n");
			set_ti_thread_flag(ti, TIF_BREAKPOINT);

			/*
			 * We stepped into an exception, interrupt or
			 * syscall handler. Some exception handlers
			 * don't check for pending work, so we need to
			 * set up a trampoline just in case.
			 *
			 * The exception entry code will undo the
			 * trampoline stuff if it does a full context
			 * save (which also means that it'll check for
			 * pending work later.)
			 */
			if ((regs->sr & MODE_MASK) == MODE_EXCEPTION) {
				trampoline_addr
					= (unsigned long)&debug_trampoline;

				pr_debug("Setting up trampoline...\n");
				ti->rar_saved = sysreg_read(RAR_EX);
				ti->rsr_saved = sysreg_read(RSR_EX);
				sysreg_write(RAR_EX, trampoline_addr);
				sysreg_write(RSR_EX, (MODE_EXCEPTION
							| SR_EM | SR_GM));
				BUG_ON(ti->rsr_saved & MODE_MASK);
			}

			/*
			 * If we stepped into a system call, we
			 * shouldn't do a single step after we return
			 * since the return address is right after the
			 * "scall" instruction we were told to step
			 * over.
			 */
			if ((regs->sr & MODE_MASK) == MODE_SUPERVISOR) {
				pr_debug("Supervisor; no single step\n");
				clear_ti_thread_flag(ti, TIF_SINGLE_STEP);
			}

			ctrl = ocd_read(DC);
			ctrl &= ~(1 << OCD_DC_SS_BIT);
			ocd_write(DC, ctrl);

			return regs;
		} else {
			printk(KERN_ERR "Unexpected OCD_DS value: 0x%08x\n",
					status);
			printk(KERN_ERR "Thread flags: 0x%08lx\n", ti->flags);
			die("Unhandled debug trap in kernel mode",
					regs, SIGTRAP);
		}
	} else if (status & (1 << OCD_DS_SSS_BIT)) {
		/* Single step in user mode */
		code = TRAP_TRACE;

		ctrl = ocd_read(DC);
		ctrl &= ~(1 << OCD_DC_SS_BIT);
		ocd_write(DC, ctrl);
	}

	pr_debug("Sending SIGTRAP: code=%d PC=0x%08lx SR=0x%08lx\n",
			code, regs->pc, regs->sr);

	clear_thread_flag(TIF_SINGLE_STEP);
	_exception(SIGTRAP, regs, code, instruction_pointer(regs));

	return regs;
}
