/* MN10300  Process handling code
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/user.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/percpu.h>
#include <linux/err.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/rcupdate.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/mmu_context.h>
#include <asm/fpu.h>
#include <asm/reset-regs.h>
#include <asm/gdb-stub.h>
#include "internal.h"

/*
 * power management idle function, if any..
 */
void (*pm_idle)(void);
EXPORT_SYMBOL(pm_idle);

/*
 * return saved PC of a blocked thread.
 */
unsigned long thread_saved_pc(struct task_struct *tsk)
{
	return ((unsigned long *) tsk->thread.sp)[3];
}

/*
 * power off function, if any
 */
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);

#if !defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
/*
 * we use this if we don't have any better idle routine
 */
static void default_idle(void)
{
	local_irq_disable();
	if (!need_resched())
		safe_halt();
	else
		local_irq_enable();
}

#else /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU  */
/*
 * On SMP it's slightly faster (but much more power-consuming!)
 * to poll the ->work.need_resched flag instead of waiting for the
 * cross-CPU IPI to arrive. Use this option with caution.
 */
static inline void poll_idle(void)
{
	int oldval;

	local_irq_enable();

	/*
	 * Deal with another CPU just having chosen a thread to
	 * run here:
	 */
	oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);

	if (!oldval) {
		set_thread_flag(TIF_POLLING_NRFLAG);
		while (!need_resched())
			cpu_relax();
		clear_thread_flag(TIF_POLLING_NRFLAG);
	} else {
		set_need_resched();
	}
}
#endif /* !CONFIG_SMP || CONFIG_HOTPLUG_CPU */

/*
 * the idle thread
 * - there's no useful work to be done, so just try to conserve power and have
 *   a low exit latency (ie sit in a loop waiting for somebody to say that
 *   they'd like to reschedule)
 */
void cpu_idle(void)
{
	/* endless idle loop with no priority at all */
	for (;;) {
		rcu_idle_enter();
		while (!need_resched()) {
			void (*idle)(void);

			smp_rmb();
			idle = pm_idle;
			if (!idle) {
#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
				idle = poll_idle;
#else  /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */
				idle = default_idle;
#endif /* CONFIG_SMP && !CONFIG_HOTPLUG_CPU */
			}
			idle();
		}
		rcu_idle_exit();

		schedule_preempt_disabled();
	}
}

void release_segments(struct mm_struct *mm)
{
}

void machine_restart(char *cmd)
{
#ifdef CONFIG_KERNEL_DEBUGGER
	gdbstub_exit(0);
#endif

#ifdef mn10300_unit_hard_reset
	mn10300_unit_hard_reset();
#else
	mn10300_proc_hard_reset();
#endif
}

void machine_halt(void)
{
#ifdef CONFIG_KERNEL_DEBUGGER
	gdbstub_exit(0);
#endif
}

void machine_power_off(void)
{
#ifdef CONFIG_KERNEL_DEBUGGER
	gdbstub_exit(0);
#endif
}

void show_regs(struct pt_regs *regs)
{
}

/*
 * free current thread data structures etc..
 */
void exit_thread(void)
{
	exit_fpu();
}

void flush_thread(void)
{
	flush_fpu();
}

void release_thread(struct task_struct *dead_task)
{
}

/*
 * we do not have to muck with descriptors here, that is
 * done in switch_mm() as needed.
 */
void copy_segments(struct task_struct *p, struct mm_struct *new_mm)
{
}

/*
 * this gets called so that we can store lazy state into memory and copy the
 * current task into the new thread.
 */
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
	unlazy_fpu(src);
	*dst = *src;
	return 0;
}

/*
 * set up the kernel stack for a new thread and copy arch-specific thread
 * control information
 */
int copy_thread(unsigned long clone_flags,
		unsigned long c_usp, unsigned long ustk_size,
		struct task_struct *p, struct pt_regs *kregs)
{
	struct thread_info *ti = task_thread_info(p);
	struct pt_regs *c_regs;
	unsigned long c_ksp;

	c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;

	/* allocate the userspace exception frame and set it up */
	c_ksp -= sizeof(struct pt_regs);
	c_regs = (struct pt_regs *) c_ksp;
	c_ksp -= 12; /* allocate function call ABI slack */

	/* set up things up so the scheduler can start the new task */
	p->thread.uregs = c_regs;
	ti->frame	= c_regs;
	p->thread.a3	= (unsigned long) c_regs;
	p->thread.sp	= c_ksp;
	p->thread.wchan	= p->thread.pc;
	p->thread.usp	= c_usp;

	if (unlikely(!kregs)) {
		memset(c_regs, 0, sizeof(struct pt_regs));
		c_regs->a0 = c_usp; /* function */
		c_regs->d0 = ustk_size; /* argument */
		local_save_flags(c_regs->epsw);
		c_regs->epsw |= EPSW_IE | EPSW_IM_7;
		p->thread.pc	= (unsigned long) ret_from_kernel_thread;
		return 0;
	}
	*c_regs = *kregs;
	c_regs->sp = c_usp;
	c_regs->epsw &= ~EPSW_FE; /* my FPU */

	/* the new TLS pointer is passed in as arg #5 to sys_clone() */
	if (clone_flags & CLONE_SETTLS)
		c_regs->e2 = current_frame()->d3;

	p->thread.pc	= (unsigned long) ret_from_fork;

	return 0;
}

/*
 * clone a process
 * - tlsptr is retrieved by copy_thread() from current_frame()->d3
 */
asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
			  int __user *parent_tidptr, int __user *child_tidptr,
			  int __user *tlsptr)
{
	return do_fork(clone_flags, newsp ?: current_frame()->sp,
		       current_frame(), 0, parent_tidptr, child_tidptr);
}

asmlinkage long sys_fork(void)
{
	return do_fork(SIGCHLD, current_frame()->sp,
		       current_frame(), 0, NULL, NULL);
}

asmlinkage long sys_vfork(void)
{
	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, current_frame()->sp,
		       current_frame(), 0, NULL, NULL);
}

unsigned long get_wchan(struct task_struct *p)
{
	return p->thread.wchan;
}
