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

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,
		 unsigned long addr, unsigned long data)
{
	int ret;
	void __user *datap = (void __user *) data;

	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, datap);
		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, datap);
		break;

	case PTRACE_SETREGS:
		ret = ptrace_setregs(child, datap);
		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;
}
