/**
 * @file backtrace.c
 *
 * @remark Copyright 2008 Tensilica Inc.
 * @remark Read the file COPYING
 *
 */

#include <linux/oprofile.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/ptrace.h>
#include <asm/uaccess.h>
#include <asm/traps.h>

/* Address of common_exception_return, used to check the
 * transition from kernel to user space.
 */
extern int common_exception_return;

/* A struct that maps to the part of the frame containing the a0 and
 * a1 registers.
 */
struct frame_start {
	unsigned long a0;
	unsigned long a1;
};

static void xtensa_backtrace_user(struct pt_regs *regs, unsigned int depth)
{
	unsigned long windowstart = regs->windowstart;
	unsigned long windowbase = regs->windowbase;
	unsigned long a0 = regs->areg[0];
	unsigned long a1 = regs->areg[1];
	unsigned long pc = MAKE_PC_FROM_RA(a0, regs->pc);
	int index;

	/* First add the current PC to the trace. */
	if (pc != 0 && pc <= TASK_SIZE)
		oprofile_add_trace(pc);
	else
		return;

	/* Two steps:
	 *
	 * 1. Look through the register window for the
	 * previous PCs in the call trace.
	 *
	 * 2. Look on the stack.
	 */

	/* Step 1.  */
	/* Rotate WINDOWSTART to move the bit corresponding to
	 * the current window to the bit #0.
	 */
	windowstart = (windowstart << WSBITS | windowstart) >> windowbase;

	/* Look for bits that are set, they correspond to
	 * valid windows.
	 */
	for (index = WSBITS - 1; (index > 0) && depth; depth--, index--)
		if (windowstart & (1 << index)) {
			/* Read a0 and a1 from the
			 * corresponding position in AREGs.
			 */
			a0 = regs->areg[index * 4];
			a1 = regs->areg[index * 4 + 1];
			/* Get the PC from a0 and a1. */
			pc = MAKE_PC_FROM_RA(a0, pc);

			/* Add the PC to the trace. */
			if (pc != 0 && pc <= TASK_SIZE)
				oprofile_add_trace(pc);
			else
				return;
		}

	/* Step 2. */
	/* We are done with the register window, we need to
	 * look through the stack.
	 */
	if (depth > 0) {
		/* Start from the a1 register. */
		/* a1 = regs->areg[1]; */
		while (a0 != 0 && depth--) {

			struct frame_start frame_start;
			/* Get the location for a1, a0 for the
			 * previous frame from the current a1.
			 */
			unsigned long *psp = (unsigned long *)a1;
			psp -= 4;

			/* Check if the region is OK to access. */
			if (!access_ok(VERIFY_READ, psp, sizeof(frame_start)))
				return;
			/* Copy a1, a0 from user space stack frame. */
			if (__copy_from_user_inatomic(&frame_start, psp,
						sizeof(frame_start)))
				return;

			a0 = frame_start.a0;
			a1 = frame_start.a1;
			pc = MAKE_PC_FROM_RA(a0, pc);

			if (pc != 0 && pc <= TASK_SIZE)
				oprofile_add_trace(pc);
			else
				return;
		}
	}
}

static void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth)
{
	unsigned long pc = regs->pc;
	unsigned long *psp;
	unsigned long sp_start, sp_end;
	unsigned long a0 = regs->areg[0];
	unsigned long a1 = regs->areg[1];

	sp_start = a1 & ~(THREAD_SIZE-1);
	sp_end = sp_start + THREAD_SIZE;

	/* Spill the register window to the stack first. */
	spill_registers();

	/* Read the stack frames one by one and create the PC
	 * from the a0 and a1 registers saved there.
	 */
	while (a1 > sp_start && a1 < sp_end && depth--) {
		pc = MAKE_PC_FROM_RA(a0, pc);

		/* Add the PC to the trace. */
		oprofile_add_trace(pc);
		if (pc == (unsigned long) &common_exception_return) {
			regs = (struct pt_regs *)a1;
			if (user_mode(regs)) {
				pc = regs->pc;
				if (pc != 0 && pc <= TASK_SIZE)
					oprofile_add_trace(pc);
				else
					return;
				return xtensa_backtrace_user(regs, depth);
			}
			a0 = regs->areg[0];
			a1 = regs->areg[1];
			continue;
		}

		psp = (unsigned long *)a1;

		a0 = *(psp - 4);
		a1 = *(psp - 3);

		if (a1 <= (unsigned long)psp)
			return;

	}
	return;
}

void xtensa_backtrace(struct pt_regs * const regs, unsigned int depth)
{
	if (user_mode(regs))
		xtensa_backtrace_user(regs, depth);
	else
		xtensa_backtrace_kernel(regs, depth);
}
