/*
 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 * Licensed under the GPL
 */

#include "linux/percpu.h"
#include "asm/pgalloc.h"
#include "asm/tlb.h"

#ifdef CONFIG_SMP

#include "linux/sched.h"
#include "linux/module.h"
#include "linux/threads.h"
#include "linux/interrupt.h"
#include "linux/err.h"
#include "linux/hardirq.h"
#include "asm/smp.h"
#include "asm/processor.h"
#include "asm/spinlock.h"
#include "kern.h"
#include "irq_user.h"
#include "os.h"

/* Per CPU bogomips and other parameters
 * The only piece used here is the ipi pipe, which is set before SMP is
 * started and never changed.
 */
struct cpuinfo_um cpu_data[NR_CPUS];

/* A statistic, can be a little off */
int num_reschedules_sent = 0;

/* Not changed after boot */
struct task_struct *idle_threads[NR_CPUS];

void smp_send_reschedule(int cpu)
{
	os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
	num_reschedules_sent++;
}

void smp_send_stop(void)
{
	int i;

	printk(KERN_INFO "Stopping all CPUs...");
	for (i = 0; i < num_online_cpus(); i++) {
		if (i == current_thread->cpu)
			continue;
		os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
	}
	printk(KERN_CONT "done\n");
}

static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
static cpumask_t cpu_callin_map = CPU_MASK_NONE;

static int idle_proc(void *cpup)
{
	int cpu = (int) cpup, err;

	err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
	if (err < 0)
		panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);

	os_set_fd_async(cpu_data[cpu].ipi_pipe[0]);

	wmb();
	if (cpu_test_and_set(cpu, cpu_callin_map)) {
		printk(KERN_ERR "huh, CPU#%d already present??\n", cpu);
		BUG();
	}

	while (!cpu_isset(cpu, smp_commenced_mask))
		cpu_relax();

	notify_cpu_starting(cpu);
	cpu_set(cpu, cpu_online_map);
	default_idle();
	return 0;
}

static struct task_struct *idle_thread(int cpu)
{
	struct task_struct *new_task;

	current->thread.request.u.thread.proc = idle_proc;
	current->thread.request.u.thread.arg = (void *) cpu;
	new_task = fork_idle(cpu);
	if (IS_ERR(new_task))
		panic("copy_process failed in idle_thread, error = %ld",
		      PTR_ERR(new_task));

	cpu_tasks[cpu] = ((struct cpu_task)
		          { .pid = 	new_task->thread.mode.tt.extern_pid,
			    .task = 	new_task } );
	idle_threads[cpu] = new_task;
	panic("skas mode doesn't support SMP");
	return new_task;
}

void smp_prepare_cpus(unsigned int maxcpus)
{
	struct task_struct *idle;
	unsigned long waittime;
	int err, cpu, me = smp_processor_id();
	int i;

	for (i = 0; i < ncpus; ++i)
		set_cpu_possible(i, true);

	cpu_clear(me, cpu_online_map);
	cpu_set(me, cpu_online_map);
	cpu_set(me, cpu_callin_map);

	err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
	if (err < 0)
		panic("CPU#0 failed to create IPI pipe, errno = %d", -err);

	os_set_fd_async(cpu_data[me].ipi_pipe[0]);

	for (cpu = 1; cpu < ncpus; cpu++) {
		printk(KERN_INFO "Booting processor %d...\n", cpu);

		idle = idle_thread(cpu);

		init_idle(idle, cpu);

		waittime = 200000000;
		while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
			cpu_relax();

		printk(KERN_INFO "%s\n",
		       cpu_isset(cpu, cpu_calling_map) ? "done" : "failed");
	}
}

void smp_prepare_boot_cpu(void)
{
	cpu_set(smp_processor_id(), cpu_online_map);
}

int __cpu_up(unsigned int cpu)
{
	cpu_set(cpu, smp_commenced_mask);
	while (!cpu_isset(cpu, cpu_online_map))
		mb();
	return 0;
}

int setup_profiling_timer(unsigned int multiplier)
{
	printk(KERN_INFO "setup_profiling_timer\n");
	return 0;
}

void smp_call_function_slave(int cpu);

void IPI_handler(int cpu)
{
	unsigned char c;
	int fd;

	fd = cpu_data[cpu].ipi_pipe[0];
	while (os_read_file(fd, &c, 1) == 1) {
		switch (c) {
		case 'C':
			smp_call_function_slave(cpu);
			break;

		case 'R':
			scheduler_ipi();
			break;

		case 'S':
			printk(KERN_INFO "CPU#%d stopping\n", cpu);
			while (1)
				pause();
			break;

		default:
			printk(KERN_ERR "CPU#%d received unknown IPI [%c]!\n",
			       cpu, c);
			break;
		}
	}
}

int hard_smp_processor_id(void)
{
	return pid_to_processor_id(os_getpid());
}

static DEFINE_SPINLOCK(call_lock);
static atomic_t scf_started;
static atomic_t scf_finished;
static void (*func)(void *info);
static void *info;

void smp_call_function_slave(int cpu)
{
	atomic_inc(&scf_started);
	(*func)(info);
	atomic_inc(&scf_finished);
}

int smp_call_function(void (*_func)(void *info), void *_info, int wait)
{
	int cpus = num_online_cpus() - 1;
	int i;

	if (!cpus)
		return 0;

	/* Can deadlock when called with interrupts disabled */
	WARN_ON(irqs_disabled());

	spin_lock_bh(&call_lock);
	atomic_set(&scf_started, 0);
	atomic_set(&scf_finished, 0);
	func = _func;
	info = _info;

	for_each_online_cpu(i)
		os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);

	while (atomic_read(&scf_started) != cpus)
		barrier();

	if (wait)
		while (atomic_read(&scf_finished) != cpus)
			barrier();

	spin_unlock_bh(&call_lock);
	return 0;
}

#endif
