/*
 * Architecture-dependent parts of process handling.
 *
 * Copyright (C) 2013 Altera Corporation
 * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
 * Copyright (C) 2009 Wind River Systems Inc
 *   Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
 * Copyright (C) 2004 Microtronix Datacom Ltd
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/export.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task.h>
#include <linux/sched/task_stack.h>
#include <linux/mm_types.h>
#include <linux/tick.h>
#include <linux/uaccess.h>

#include <asm/unistd.h>
#include <asm/traps.h>
#include <asm/cpuinfo.h>

asmlinkage void ret_from_fork(void);
asmlinkage void ret_from_kernel_thread(void);

void (*pm_power_off)(void) = NULL;
EXPORT_SYMBOL(pm_power_off);

void arch_cpu_idle(void)
{
}

/*
 * The development boards have no way to pull a board reset. Just jump to the
 * cpu reset address and let the boot loader or the code in head.S take care of
 * resetting peripherals.
 */
void machine_restart(char *__unused)
{
	pr_notice("Machine restart (%08x)...\n", cpuinfo.reset_addr);
	local_irq_disable();
	__asm__ __volatile__ (
	"jmp	%0\n\t"
	:
	: "r" (cpuinfo.reset_addr)
	: "r4");
}

void machine_halt(void)
{
	pr_notice("Machine halt...\n");
	local_irq_disable();
	for (;;)
		;
}

/*
 * There is no way to power off the development boards. So just spin for now. If
 * we ever have a way of resetting a board using a GPIO we should add that here.
 */
void machine_power_off(void)
{
	pr_notice("Machine power off...\n");
	local_irq_disable();
	for (;;)
		;
}

void show_regs(struct pt_regs *regs)
{
	pr_notice("\n");
	show_regs_print_info(KERN_DEFAULT);

	pr_notice("r1: %08lx r2: %08lx r3: %08lx r4: %08lx\n",
		regs->r1,  regs->r2,  regs->r3,  regs->r4);

	pr_notice("r5: %08lx r6: %08lx r7: %08lx r8: %08lx\n",
		regs->r5,  regs->r6,  regs->r7,  regs->r8);

	pr_notice("r9: %08lx r10: %08lx r11: %08lx r12: %08lx\n",
		regs->r9,  regs->r10, regs->r11, regs->r12);

	pr_notice("r13: %08lx r14: %08lx r15: %08lx\n",
		regs->r13, regs->r14, regs->r15);

	pr_notice("ra: %08lx fp:  %08lx sp: %08lx gp: %08lx\n",
		regs->ra,  regs->fp,  regs->sp,  regs->gp);

	pr_notice("ea: %08lx estatus: %08lx\n",
		regs->ea,  regs->estatus);
}

void flush_thread(void)
{
}

int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
	unsigned long clone_flags = args->flags;
	unsigned long usp = args->stack;
	unsigned long tls = args->tls;
	struct pt_regs *childregs = task_pt_regs(p);
	struct pt_regs *regs;
	struct switch_stack *stack;
	struct switch_stack *childstack =
		((struct switch_stack *)childregs) - 1;

	if (unlikely(args->fn)) {
		memset(childstack, 0,
			sizeof(struct switch_stack) + sizeof(struct pt_regs));

		childstack->r16 = (unsigned long) args->fn;
		childstack->r17 = (unsigned long) args->fn_arg;
		childstack->ra = (unsigned long) ret_from_kernel_thread;
		childregs->estatus = STATUS_PIE;
		childregs->sp = (unsigned long) childstack;

		p->thread.ksp = (unsigned long) childstack;
		p->thread.kregs = childregs;
		return 0;
	}

	regs = current_pt_regs();
	*childregs = *regs;
	childregs->r2 = 0;	/* Set the return value for the child. */
	childregs->r7 = 0;

	stack = ((struct switch_stack *) regs) - 1;
	*childstack = *stack;
	childstack->ra = (unsigned long)ret_from_fork;
	p->thread.kregs = childregs;
	p->thread.ksp = (unsigned long) childstack;

	if (usp)
		childregs->sp = usp;

	/* Initialize tls register. */
	if (clone_flags & CLONE_SETTLS)
		childstack->r23 = tls;

	return 0;
}

/*
 *	Generic dumping code. Used for panic and debug.
 */
void dump(struct pt_regs *fp)
{
	unsigned long	*sp;
	unsigned char	*tp;
	int		i;

	pr_emerg("\nCURRENT PROCESS:\n\n");
	pr_emerg("COMM=%s PID=%d\n", current->comm, current->pid);

	if (current->mm) {
		pr_emerg("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
			(int) current->mm->start_code,
			(int) current->mm->end_code,
			(int) current->mm->start_data,
			(int) current->mm->end_data,
			(int) current->mm->end_data,
			(int) current->mm->brk);
		pr_emerg("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
			(int) current->mm->start_stack,
			(int)(((unsigned long) current) + THREAD_SIZE));
	}

	pr_emerg("PC: %08lx\n", fp->ea);
	pr_emerg("SR: %08lx    SP: %08lx\n",
		(long) fp->estatus, (long) fp);

	pr_emerg("r1: %08lx    r2: %08lx    r3: %08lx\n",
		fp->r1, fp->r2, fp->r3);

	pr_emerg("r4: %08lx    r5: %08lx    r6: %08lx    r7: %08lx\n",
		fp->r4, fp->r5, fp->r6, fp->r7);
	pr_emerg("r8: %08lx    r9: %08lx    r10: %08lx    r11: %08lx\n",
		fp->r8, fp->r9, fp->r10, fp->r11);
	pr_emerg("r12: %08lx  r13: %08lx    r14: %08lx    r15: %08lx\n",
		fp->r12, fp->r13, fp->r14, fp->r15);
	pr_emerg("or2: %08lx   ra: %08lx     fp: %08lx    sp: %08lx\n",
		fp->orig_r2, fp->ra, fp->fp, fp->sp);
	pr_emerg("\nUSP: %08x   TRAPFRAME: %08x\n",
		(unsigned int) fp->sp, (unsigned int) fp);

	pr_emerg("\nCODE:");
	tp = ((unsigned char *) fp->ea) - 0x20;
	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
		if ((i % 0x10) == 0)
			pr_emerg("\n%08x: ", (int) (tp + i));
		pr_emerg("%08x ", (int) *sp++);
	}
	pr_emerg("\n");

	pr_emerg("\nKERNEL STACK:");
	tp = ((unsigned char *) fp) - 0x40;
	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
		if ((i % 0x10) == 0)
			pr_emerg("\n%08x: ", (int) (tp + i));
		pr_emerg("%08x ", (int) *sp++);
	}
	pr_emerg("\n");
	pr_emerg("\n");

	pr_emerg("\nUSER STACK:");
	tp = (unsigned char *) (fp->sp - 0x10);
	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
		if ((i % 0x10) == 0)
			pr_emerg("\n%08x: ", (int) (tp + i));
		pr_emerg("%08x ", (int) *sp++);
	}
	pr_emerg("\n\n");
}

unsigned long __get_wchan(struct task_struct *p)
{
	unsigned long fp, pc;
	unsigned long stack_page;
	int count = 0;

	stack_page = (unsigned long)p;
	fp = ((struct switch_stack *)p->thread.ksp)->fp;	/* ;dgt2 */
	do {
		if (fp < stack_page+sizeof(struct task_struct) ||
			fp >= 8184+stack_page)	/* ;dgt2;tmp */
			return 0;
		pc = ((unsigned long *)fp)[1];
		if (!in_sched_functions(pc))
			return pc;
		fp = *(unsigned long *) fp;
	} while (count++ < 16);		/* ;dgt2;tmp */
	return 0;
}

/*
 * Do necessary setup to start up a newly executed thread.
 * Will startup in user mode (status_extension = 0).
 */
void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
{
	memset((void *) regs, 0, sizeof(struct pt_regs));
	regs->estatus = ESTATUS_EPIE | ESTATUS_EU;
	regs->ea = pc;
	regs->sp = sp;
}

asmlinkage int nios2_clone(unsigned long clone_flags, unsigned long newsp,
			   int __user *parent_tidptr, int __user *child_tidptr,
			   unsigned long tls)
{
	struct kernel_clone_args args = {
		.flags		= (lower_32_bits(clone_flags) & ~CSIGNAL),
		.pidfd		= parent_tidptr,
		.child_tid	= child_tidptr,
		.parent_tid	= parent_tidptr,
		.exit_signal	= (lower_32_bits(clone_flags) & CSIGNAL),
		.stack		= newsp,
		.tls		= tls,
	};

	return kernel_clone(&args);
}
