/*
 * Copyright (C) 2000-2007, Axis Communications AB.
 */

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/signal.h>
#include <linux/security.h>

#include <linux/uaccess.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <arch/hwregs/supp_reg.h>

/*
 * Determines which bits in CCS the user has access to.
 * 1 = access, 0 = no access.
 */
#define CCS_MASK 0x00087c00     /* SXNZVC */

#define SBIT_USER (1 << (S_CCS_BITNR + CCS_SHIFT))

static int put_debugreg(long pid, unsigned int regno, long data);
static long get_debugreg(long pid, unsigned int regno);
static unsigned long get_pseudo_pc(struct task_struct *child);
void deconfigure_bp(long pid);

extern unsigned long cris_signal_return_page;

/*
 * Get contents of register REGNO in task TASK.
 */
long get_reg(struct task_struct *task, unsigned int regno)
{
	/* USP is a special case, it's not in the pt_regs struct but
	 * in the tasks thread struct
	 */
	unsigned long ret;

	if (regno <= PT_EDA)
		ret = ((unsigned long *)task_pt_regs(task))[regno];
	else if (regno == PT_USP)
		ret = task->thread.usp;
	else if (regno == PT_PPC)
		ret = get_pseudo_pc(task);
	else if (regno <= PT_MAX)
		ret = get_debugreg(task->pid, regno);
	else
		ret = 0;

	return ret;
}

/*
 * Write contents of register REGNO in task TASK.
 */
int put_reg(struct task_struct *task, unsigned int regno, unsigned long data)
{
	if (regno <= PT_EDA)
		((unsigned long *)task_pt_regs(task))[regno] = data;
	else if (regno == PT_USP)
		task->thread.usp = data;
	else if (regno == PT_PPC) {
		/* Write pseudo-PC to ERP only if changed. */
		if (data != get_pseudo_pc(task))
			task_pt_regs(task)->erp = data;
	} else if (regno <= PT_MAX)
		return put_debugreg(task->pid, regno, data);
	else
		return -1;
	return 0;
}

void user_enable_single_step(struct task_struct *child)
{
	unsigned long tmp;

	/*
	 * Set up SPC if not set already (in which case we have no other
	 * choice but to trust it).
	 */
	if (!get_reg(child, PT_SPC)) {
		/* In case we're stopped in a delay slot. */
		tmp = get_reg(child, PT_ERP) & ~1;
		put_reg(child, PT_SPC, tmp);
	}
	tmp = get_reg(child, PT_CCS) | SBIT_USER;
	put_reg(child, PT_CCS, tmp);
}

void user_disable_single_step(struct task_struct *child)
{
	put_reg(child, PT_SPC, 0);

	if (!get_debugreg(child->pid, PT_BP_CTRL)) {
		unsigned long tmp;
		/* If no h/w bp configured, disable S bit. */
		tmp = get_reg(child, PT_CCS) & ~SBIT_USER;
		put_reg(child, PT_CCS, tmp);
	}
}

/*
 * Called by kernel/ptrace.c when detaching.
 *
 * Make sure the single step bit is not set.
 */
void
ptrace_disable(struct task_struct *child)
{
	/* Deconfigure SPC and S-bit. */
	user_disable_single_step(child);
	put_reg(child, PT_SPC, 0);

	/* Deconfigure any watchpoints associated with the child. */
	deconfigure_bp(child->pid);
}


long arch_ptrace(struct task_struct *child, long request,
		 unsigned long addr, unsigned long data)
{
	int ret;
	unsigned int regno = addr >> 2;
	unsigned long __user *datap = (unsigned long __user *)data;

	switch (request) {
		/* Read word at location address. */
		case PTRACE_PEEKTEXT:
		case PTRACE_PEEKDATA: {
			unsigned long tmp;
			int copied;

			ret = -EIO;

			/* The signal trampoline page is outside the normal user-addressable
			 * space but still accessible. This is hack to make it possible to
			 * access the signal handler code in GDB.
			 */
			if ((addr & PAGE_MASK) == cris_signal_return_page) {
				/* The trampoline page is globally mapped, no page table to traverse.*/
				tmp = *(unsigned long*)addr;
			} else {
				copied = ptrace_access_vm(child, addr, &tmp, sizeof(tmp), FOLL_FORCE);

				if (copied != sizeof(tmp))
					break;
			}

			ret = put_user(tmp,datap);
			break;
		}

		/* Read the word at location address in the USER area. */
		case PTRACE_PEEKUSR: {
			unsigned long tmp;

			ret = -EIO;
			if ((addr & 3) || regno > PT_MAX)
				break;

			tmp = get_reg(child, regno);
			ret = put_user(tmp, datap);
			break;
		}

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

		/* Write the word at location address in the USER area. */
		case PTRACE_POKEUSR:
			ret = -EIO;
			if ((addr & 3) || regno > PT_MAX)
				break;

			if (regno == PT_CCS) {
				/* don't allow the tracing process to change stuff like
				 * interrupt enable, kernel/user bit, dma enables etc.
				 */
				data &= CCS_MASK;
				data |= get_reg(child, PT_CCS) & ~CCS_MASK;
			}
			if (put_reg(child, regno, data))
				break;
			ret = 0;
			break;

		/* Get all GP registers from the child. */
		case PTRACE_GETREGS: {
			int i;
			unsigned long tmp;

			for (i = 0; i <= PT_MAX; i++) {
				tmp = get_reg(child, i);

				if (put_user(tmp, datap)) {
					ret = -EFAULT;
					goto out_tsk;
				}

				datap++;
			}

			ret = 0;
			break;
		}

		/* Set all GP registers in the child. */
		case PTRACE_SETREGS: {
			int i;
			unsigned long tmp;

			for (i = 0; i <= PT_MAX; i++) {
				if (get_user(tmp, datap)) {
					ret = -EFAULT;
					goto out_tsk;
				}

				if (i == PT_CCS) {
					tmp &= CCS_MASK;
					tmp |= get_reg(child, PT_CCS) & ~CCS_MASK;
				}

				put_reg(child, i, tmp);
				datap++;
			}

			ret = 0;
			break;
		}

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

out_tsk:
	return ret;
}

void do_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.
	 */
	if (current->exit_code) {
		send_sig(current->exit_code, current, 1);
		current->exit_code = 0;
	}
}

/* Returns the size of an instruction that has a delay slot. */

static int insn_size(struct task_struct *child, unsigned long pc)
{
  unsigned long opcode;
  int copied;
  int opsize = 0;

  /* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */
  copied = access_process_vm(child, pc, &opcode, sizeof(opcode), FOLL_FORCE);
  if (copied != sizeof(opcode))
    return 0;

  switch ((opcode & 0x0f00) >> 8) {
  case 0x0:
  case 0x9:
  case 0xb:
	  opsize = 2;
	  break;
  case 0xe:
  case 0xf:
	  opsize = 6;
	  break;
  case 0xd:
	  /* Could be 4 or 6; check more bits. */
	  if ((opcode & 0xff) == 0xff)
		  opsize = 4;
	  else
		  opsize = 6;
	  break;
  default:
	  panic("ERROR: Couldn't find size of opcode 0x%lx at 0x%lx\n",
		opcode, pc);
  }

  return opsize;
}

static unsigned long get_pseudo_pc(struct task_struct *child)
{
	/* Default value for PC is ERP. */
	unsigned long pc = get_reg(child, PT_ERP);

	if (pc & 0x1) {
		unsigned long spc = get_reg(child, PT_SPC);
		/* Delay slot bit set. Report as stopped on proper
		   instruction. */
		if (spc) {
			/* Rely on SPC if set. FIXME: We might want to check
			   that EXS indicates we stopped due to a single-step
			   exception. */
			pc = spc;
		} else {
			/* Calculate the PC from the size of the instruction
			   that the delay slot we're in belongs to. */
			pc += insn_size(child, pc & ~1) - 1;
		}
	}
	return pc;
}

static long bp_owner = 0;

/* Reachable from exit_thread in signal.c, so not static. */
void deconfigure_bp(long pid)
{
	int bp;

	/* Only deconfigure if the pid is the owner. */
	if (bp_owner != pid)
		return;

	for (bp = 0; bp < 6; bp++) {
		unsigned long tmp;
		/* Deconfigure start and end address (also gets rid of ownership). */
		put_debugreg(pid, PT_BP + 3 + (bp * 2), 0);
		put_debugreg(pid, PT_BP + 4 + (bp * 2), 0);

		/* Deconfigure relevant bits in control register. */
		tmp = get_debugreg(pid, PT_BP_CTRL) & ~(3 << (2 + (bp * 4)));
		put_debugreg(pid, PT_BP_CTRL, tmp);
	}
	/* No owner now. */
	bp_owner = 0;
}

static int put_debugreg(long pid, unsigned int regno, long data)
{
	int ret = 0;
	register int old_srs;

#ifdef CONFIG_ETRAX_KGDB
	/* Ignore write, but pretend it was ok if value is 0
	   (we don't want POKEUSR/SETREGS failing unnessecarily). */
	return (data == 0) ? ret : -1;
#endif

	/* Simple owner management. */
	if (!bp_owner)
		bp_owner = pid;
	else if (bp_owner != pid) {
		/* Ignore write, but pretend it was ok if value is 0
		   (we don't want POKEUSR/SETREGS failing unnessecarily). */
		return (data == 0) ? ret : -1;
	}

	/* Remember old SRS. */
	SPEC_REG_RD(SPEC_REG_SRS, old_srs);
	/* Switch to BP bank. */
	SUPP_BANK_SEL(BANK_BP);

	switch (regno - PT_BP) {
	case 0:
		SUPP_REG_WR(0, data); break;
	case 1:
	case 2:
		if (data)
			ret = -1;
		break;
	case 3:
		SUPP_REG_WR(3, data); break;
	case 4:
		SUPP_REG_WR(4, data); break;
	case 5:
		SUPP_REG_WR(5, data); break;
	case 6:
		SUPP_REG_WR(6, data); break;
	case 7:
		SUPP_REG_WR(7, data); break;
	case 8:
		SUPP_REG_WR(8, data); break;
	case 9:
		SUPP_REG_WR(9, data); break;
	case 10:
		SUPP_REG_WR(10, data); break;
	case 11:
		SUPP_REG_WR(11, data); break;
	case 12:
		SUPP_REG_WR(12, data); break;
	case 13:
		SUPP_REG_WR(13, data); break;
	case 14:
		SUPP_REG_WR(14, data); break;
	default:
		ret = -1;
		break;
	}

	/* Restore SRS. */
	SPEC_REG_WR(SPEC_REG_SRS, old_srs);
	/* Just for show. */
	NOP();
	NOP();
	NOP();

	return ret;
}

static long get_debugreg(long pid, unsigned int regno)
{
	register int old_srs;
	register long data;

	if (pid != bp_owner) {
		return 0;
	}

	/* Remember old SRS. */
	SPEC_REG_RD(SPEC_REG_SRS, old_srs);
	/* Switch to BP bank. */
	SUPP_BANK_SEL(BANK_BP);

	switch (regno - PT_BP) {
	case 0:
		SUPP_REG_RD(0, data); break;
	case 1:
	case 2:
		/* error return value? */
		data = 0;
		break;
	case 3:
		SUPP_REG_RD(3, data); break;
	case 4:
		SUPP_REG_RD(4, data); break;
	case 5:
		SUPP_REG_RD(5, data); break;
	case 6:
		SUPP_REG_RD(6, data); break;
	case 7:
		SUPP_REG_RD(7, data); break;
	case 8:
		SUPP_REG_RD(8, data); break;
	case 9:
		SUPP_REG_RD(9, data); break;
	case 10:
		SUPP_REG_RD(10, data); break;
	case 11:
		SUPP_REG_RD(11, data); break;
	case 12:
		SUPP_REG_RD(12, data); break;
	case 13:
		SUPP_REG_RD(13, data); break;
	case 14:
		SUPP_REG_RD(14, data); break;
	default:
		/* error return value? */
		data = 0;
	}

	/* Restore SRS. */
	SPEC_REG_WR(SPEC_REG_SRS, old_srs);
	/* Just for show. */
	NOP();
	NOP();
	NOP();

	return data;
}
