/*
 * 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 user_enable_single_step(struct task_struct *tsk)
{
	pr_debug("user_enable_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);
}

void user_disable_single_step(struct task_struct *child)
{
	/* XXX(hch): a no-op here seems wrong.. */
}

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

	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;
}
