/*
 * Copyright (C) 2004, 2005 MIPS Technologies, Inc.  All rights reserved.
 *
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License (Version 2) as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 */

/*
 * VPE support module
 *
 * Provides support for loading a MIPS SP program on VPE1.
 * The SP enviroment is rather simple, no tlb's.  It needs to be relocatable
 * (or partially linked). You should initialise your stack in the startup
 * code. This loader looks for the symbol __start and sets up
 * execution to resume from there. The MIPS SDE kit contains suitable examples.
 *
 * To load and run, simply cat a SP 'program file' to /dev/vpe1.
 * i.e cat spapp >/dev/vpe1.
 */
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/elf.h>
#include <linux/seq_file.h>
#include <linux/smp_lock.h>
#include <linux/syscalls.h>
#include <linux/moduleloader.h>
#include <linux/interrupt.h>
#include <linux/poll.h>
#include <linux/bootmem.h>
#include <asm/mipsregs.h>
#include <asm/mipsmtregs.h>
#include <asm/cacheflush.h>
#include <asm/atomic.h>
#include <asm/cpu.h>
#include <asm/mips_mt.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/vpe.h>
#include <asm/kspd.h>

typedef void *vpe_handle;

#ifndef ARCH_SHF_SMALL
#define ARCH_SHF_SMALL 0
#endif

/* If this is set, the section belongs in the init part of the module */
#define INIT_OFFSET_MASK (1UL << (BITS_PER_LONG-1))

/*
 * The number of TCs and VPEs physically available on the core
 */
static int hw_tcs, hw_vpes;
static char module_name[] = "vpe";
static int major;
static const int minor = 1;	/* fixed for now  */

#ifdef CONFIG_MIPS_APSP_KSPD
static struct kspd_notifications kspd_events;
static int kspd_events_reqd;
#endif

/* grab the likely amount of memory we will need. */
#ifdef CONFIG_MIPS_VPE_LOADER_TOM
#define P_SIZE (2 * 1024 * 1024)
#else
/* add an overhead to the max kmalloc size for non-striped symbols/etc */
#define P_SIZE (256 * 1024)
#endif

extern unsigned long physical_memsize;

#define MAX_VPES 16
#define VPE_PATH_MAX 256

enum vpe_state {
	VPE_STATE_UNUSED = 0,
	VPE_STATE_INUSE,
	VPE_STATE_RUNNING
};

enum tc_state {
	TC_STATE_UNUSED = 0,
	TC_STATE_INUSE,
	TC_STATE_RUNNING,
	TC_STATE_DYNAMIC
};

struct vpe {
	enum vpe_state state;

	/* (device) minor associated with this vpe */
	int minor;

	/* elfloader stuff */
	void *load_addr;
	unsigned long len;
	char *pbuffer;
	unsigned long plen;
	unsigned int uid, gid;
	char cwd[VPE_PATH_MAX];

	unsigned long __start;

	/* tc's associated with this vpe */
	struct list_head tc;

	/* The list of vpe's */
	struct list_head list;

	/* shared symbol address */
	void *shared_ptr;

	/* the list of who wants to know when something major happens */
	struct list_head notify;

	unsigned int ntcs;
};

struct tc {
	enum tc_state state;
	int index;

	struct vpe *pvpe;	/* parent VPE */
	struct list_head tc;	/* The list of TC's with this VPE */
	struct list_head list;	/* The global list of tc's */
};

struct {
	/* Virtual processing elements */
	struct list_head vpe_list;

	/* Thread contexts */
	struct list_head tc_list;
} vpecontrol = {
	.vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list),
	.tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
};

static void release_progmem(void *ptr);

/* get the vpe associated with this minor */
static struct vpe *get_vpe(int minor)
{
	struct vpe *v;

	if (!cpu_has_mipsmt)
		return NULL;

	list_for_each_entry(v, &vpecontrol.vpe_list, list) {
		if (v->minor == minor)
			return v;
	}

	return NULL;
}

/* get the vpe associated with this minor */
static struct tc *get_tc(int index)
{
	struct tc *t;

	list_for_each_entry(t, &vpecontrol.tc_list, list) {
		if (t->index == index)
			return t;
	}

	return NULL;
}

/* allocate a vpe and associate it with this minor (or index) */
static struct vpe *alloc_vpe(int minor)
{
	struct vpe *v;

	if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) {
		return NULL;
	}

	INIT_LIST_HEAD(&v->tc);
	list_add_tail(&v->list, &vpecontrol.vpe_list);

	INIT_LIST_HEAD(&v->notify);
	v->minor = minor;
	return v;
}

/* allocate a tc. At startup only tc0 is running, all other can be halted. */
static struct tc *alloc_tc(int index)
{
	struct tc *tc;

	if ((tc = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL)
		goto out;

	INIT_LIST_HEAD(&tc->tc);
	tc->index = index;
	list_add_tail(&tc->list, &vpecontrol.tc_list);

out:
	return tc;
}

/* clean up and free everything */
static void release_vpe(struct vpe *v)
{
	list_del(&v->list);
	if (v->load_addr)
		release_progmem(v);
	kfree(v);
}

static void dump_mtregs(void)
{
	unsigned long val;

	val = read_c0_config3();
	printk("config3 0x%lx MT %ld\n", val,
	       (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT);

	val = read_c0_mvpcontrol();
	printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val,
	       (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT,
	       (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT,
	       (val & MVPCONTROL_EVP));

	val = read_c0_mvpconf0();
	printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val,
	       (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT,
	       val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT);
}

/* Find some VPE program space  */
static void *alloc_progmem(unsigned long len)
{
	void *addr;

#ifdef CONFIG_MIPS_VPE_LOADER_TOM
	/*
	 * This means you must tell Linux to use less memory than you
	 * physically have, for example by passing a mem= boot argument.
	 */
	addr = pfn_to_kaddr(max_low_pfn);
	memset(addr, 0, len);
#else
	/* simple grab some mem for now */
	addr = kzalloc(len, GFP_KERNEL);
#endif

	return addr;
}

static void release_progmem(void *ptr)
{
#ifndef CONFIG_MIPS_VPE_LOADER_TOM
	kfree(ptr);
#endif
}

/* Update size with this section: return offset. */
static long get_offset(unsigned long *size, Elf_Shdr * sechdr)
{
	long ret;

	ret = ALIGN(*size, sechdr->sh_addralign ? : 1);
	*size = ret + sechdr->sh_size;
	return ret;
}

/* Lay out the SHF_ALLOC sections in a way not dissimilar to how ld
   might -- code, read-only data, read-write data, small data.  Tally
   sizes, and place the offsets into sh_entsize fields: high bit means it
   belongs in init. */
static void layout_sections(struct module *mod, const Elf_Ehdr * hdr,
			    Elf_Shdr * sechdrs, const char *secstrings)
{
	static unsigned long const masks[][2] = {
		/* NOTE: all executable code must be the first section
		 * in this array; otherwise modify the text_size
		 * finder in the two loops below */
		{SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_SMALL},
		{SHF_ALLOC, SHF_WRITE | ARCH_SHF_SMALL},
		{SHF_WRITE | SHF_ALLOC, ARCH_SHF_SMALL},
		{ARCH_SHF_SMALL | SHF_ALLOC, 0}
	};
	unsigned int m, i;

	for (i = 0; i < hdr->e_shnum; i++)
		sechdrs[i].sh_entsize = ~0UL;

	for (m = 0; m < ARRAY_SIZE(masks); ++m) {
		for (i = 0; i < hdr->e_shnum; ++i) {
			Elf_Shdr *s = &sechdrs[i];

			//  || strncmp(secstrings + s->sh_name, ".init", 5) == 0)
			if ((s->sh_flags & masks[m][0]) != masks[m][0]
			    || (s->sh_flags & masks[m][1])
			    || s->sh_entsize != ~0UL)
				continue;
			s->sh_entsize =
				get_offset((unsigned long *)&mod->core_size, s);
		}

		if (m == 0)
			mod->core_text_size = mod->core_size;

	}
}


/* from module-elf32.c, but subverted a little */

struct mips_hi16 {
	struct mips_hi16 *next;
	Elf32_Addr *addr;
	Elf32_Addr value;
};

static struct mips_hi16 *mips_hi16_list;
static unsigned int gp_offs, gp_addr;

static int apply_r_mips_none(struct module *me, uint32_t *location,
			     Elf32_Addr v)
{
	return 0;
}

static int apply_r_mips_gprel16(struct module *me, uint32_t *location,
				Elf32_Addr v)
{
	int rel;

	if( !(*location & 0xffff) ) {
		rel = (int)v - gp_addr;
	}
	else {
		/* .sbss + gp(relative) + offset */
		/* kludge! */
		rel =  (int)(short)((int)v + gp_offs +
				    (int)(short)(*location & 0xffff) - gp_addr);
	}

	if( (rel > 32768) || (rel < -32768) ) {
		printk(KERN_DEBUG "VPE loader: apply_r_mips_gprel16: "
		       "relative address 0x%x out of range of gp register\n",
		       rel);
		return -ENOEXEC;
	}

	*location = (*location & 0xffff0000) | (rel & 0xffff);

	return 0;
}

static int apply_r_mips_pc16(struct module *me, uint32_t *location,
			     Elf32_Addr v)
{
	int rel;
	rel = (((unsigned int)v - (unsigned int)location));
	rel >>= 2;		// because the offset is in _instructions_ not bytes.
	rel -= 1;		// and one instruction less due to the branch delay slot.

	if( (rel > 32768) || (rel < -32768) ) {
		printk(KERN_DEBUG "VPE loader: "
 		       "apply_r_mips_pc16: relative address out of range 0x%x\n", rel);
		return -ENOEXEC;
	}

	*location = (*location & 0xffff0000) | (rel & 0xffff);

	return 0;
}

static int apply_r_mips_32(struct module *me, uint32_t *location,
			   Elf32_Addr v)
{
	*location += v;

	return 0;
}

static int apply_r_mips_26(struct module *me, uint32_t *location,
			   Elf32_Addr v)
{
	if (v % 4) {
		printk(KERN_DEBUG "VPE loader: apply_r_mips_26 "
		       " unaligned relocation\n");
		return -ENOEXEC;
	}

/*
 * Not desperately convinced this is a good check of an overflow condition
 * anyway. But it gets in the way of handling undefined weak symbols which
 * we want to set to zero.
 * if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
 * printk(KERN_ERR
 * "module %s: relocation overflow\n",
 * me->name);
 * return -ENOEXEC;
 * }
 */

	*location = (*location & ~0x03ffffff) |
		((*location + (v >> 2)) & 0x03ffffff);
	return 0;
}

static int apply_r_mips_hi16(struct module *me, uint32_t *location,
			     Elf32_Addr v)
{
	struct mips_hi16 *n;

	/*
	 * We cannot relocate this one now because we don't know the value of
	 * the carry we need to add.  Save the information, and let LO16 do the
	 * actual relocation.
	 */
	n = kmalloc(sizeof *n, GFP_KERNEL);
	if (!n)
		return -ENOMEM;

	n->addr = location;
	n->value = v;
	n->next = mips_hi16_list;
	mips_hi16_list = n;

	return 0;
}

static int apply_r_mips_lo16(struct module *me, uint32_t *location,
			     Elf32_Addr v)
{
	unsigned long insnlo = *location;
	Elf32_Addr val, vallo;
	struct mips_hi16 *l, *next;

	/* Sign extend the addend we extract from the lo insn.  */
	vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;

	if (mips_hi16_list != NULL) {

		l = mips_hi16_list;
		while (l != NULL) {
			unsigned long insn;

			/*
			 * The value for the HI16 had best be the same.
			 */
 			if (v != l->value) {
				printk(KERN_DEBUG "VPE loader: "
				       "apply_r_mips_lo16/hi16: \t"
				       "inconsistent value information\n");
				goto out_free;
			}

			/*
			 * Do the HI16 relocation.  Note that we actually don't
			 * need to know anything about the LO16 itself, except
			 * where to find the low 16 bits of the addend needed
			 * by the LO16.
			 */
			insn = *l->addr;
			val = ((insn & 0xffff) << 16) + vallo;
			val += v;

			/*
			 * Account for the sign extension that will happen in
			 * the low bits.
			 */
			val = ((val >> 16) + ((val & 0x8000) != 0)) & 0xffff;

			insn = (insn & ~0xffff) | val;
			*l->addr = insn;

			next = l->next;
			kfree(l);
			l = next;
		}

		mips_hi16_list = NULL;
	}

	/*
	 * Ok, we're done with the HI16 relocs.  Now deal with the LO16.
	 */
	val = v + vallo;
	insnlo = (insnlo & ~0xffff) | (val & 0xffff);
	*location = insnlo;

	return 0;

out_free:
	while (l != NULL) {
		next = l->next;
		kfree(l);
		l = next;
	}
	mips_hi16_list = NULL;

	return -ENOEXEC;
}

static int (*reloc_handlers[]) (struct module *me, uint32_t *location,
				Elf32_Addr v) = {
	[R_MIPS_NONE]	= apply_r_mips_none,
	[R_MIPS_32]	= apply_r_mips_32,
	[R_MIPS_26]	= apply_r_mips_26,
	[R_MIPS_HI16]	= apply_r_mips_hi16,
	[R_MIPS_LO16]	= apply_r_mips_lo16,
	[R_MIPS_GPREL16] = apply_r_mips_gprel16,
	[R_MIPS_PC16] = apply_r_mips_pc16
};

static char *rstrs[] = {
	[R_MIPS_NONE]	= "MIPS_NONE",
	[R_MIPS_32]	= "MIPS_32",
	[R_MIPS_26]	= "MIPS_26",
	[R_MIPS_HI16]	= "MIPS_HI16",
	[R_MIPS_LO16]	= "MIPS_LO16",
	[R_MIPS_GPREL16] = "MIPS_GPREL16",
	[R_MIPS_PC16] = "MIPS_PC16"
};

static int apply_relocations(Elf32_Shdr *sechdrs,
		      const char *strtab,
		      unsigned int symindex,
		      unsigned int relsec,
		      struct module *me)
{
	Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
	Elf32_Sym *sym;
	uint32_t *location;
	unsigned int i;
	Elf32_Addr v;
	int res;

	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
		Elf32_Word r_info = rel[i].r_info;

		/* This is where to make the change */
		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
			+ rel[i].r_offset;
		/* This is the symbol it is referring to */
		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
			+ ELF32_R_SYM(r_info);

		if (!sym->st_value) {
			printk(KERN_DEBUG "%s: undefined weak symbol %s\n",
			       me->name, strtab + sym->st_name);
			/* just print the warning, dont barf */
		}

		v = sym->st_value;

		res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v);
		if( res ) {
			char *r = rstrs[ELF32_R_TYPE(r_info)];
		    	printk(KERN_WARNING "VPE loader: .text+0x%x "
			       "relocation type %s for symbol \"%s\" failed\n",
			       rel[i].r_offset, r ? r : "UNKNOWN",
			       strtab + sym->st_name);
			return res;
		}
	}

	return 0;
}

static inline void save_gp_address(unsigned int secbase, unsigned int rel)
{
	gp_addr = secbase + rel;
	gp_offs = gp_addr - (secbase & 0xffff0000);
}
/* end module-elf32.c */



/* Change all symbols so that sh_value encodes the pointer directly. */
static void simplify_symbols(Elf_Shdr * sechdrs,
			    unsigned int symindex,
			    const char *strtab,
			    const char *secstrings,
			    unsigned int nsecs, struct module *mod)
{
	Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
	unsigned long secbase, bssbase = 0;
	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
	int size;

	/* find the .bss section for COMMON symbols */
	for (i = 0; i < nsecs; i++) {
		if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0) {
			bssbase = sechdrs[i].sh_addr;
			break;
		}
	}

	for (i = 1; i < n; i++) {
		switch (sym[i].st_shndx) {
		case SHN_COMMON:
			/* Allocate space for the symbol in the .bss section.
			   st_value is currently size.
			   We want it to have the address of the symbol. */

			size = sym[i].st_value;
			sym[i].st_value = bssbase;

			bssbase += size;
			break;

		case SHN_ABS:
			/* Don't need to do anything */
			break;

		case SHN_UNDEF:
			/* ret = -ENOENT; */
			break;

		case SHN_MIPS_SCOMMON:
			printk(KERN_DEBUG "simplify_symbols: ignoring SHN_MIPS_SCOMMON "
			       "symbol <%s> st_shndx %d\n", strtab + sym[i].st_name,
			       sym[i].st_shndx);
			// .sbss section
			break;

		default:
			secbase = sechdrs[sym[i].st_shndx].sh_addr;

			if (strncmp(strtab + sym[i].st_name, "_gp", 3) == 0) {
				save_gp_address(secbase, sym[i].st_value);
			}

			sym[i].st_value += secbase;
			break;
		}
	}
}

#ifdef DEBUG_ELFLOADER
static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex,
			    const char *strtab, struct module *mod)
{
	Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);

	printk(KERN_DEBUG "dump_elfsymbols: n %d\n", n);
	for (i = 1; i < n; i++) {
		printk(KERN_DEBUG " i %d name <%s> 0x%x\n", i,
		       strtab + sym[i].st_name, sym[i].st_value);
	}
}
#endif

/* We are prepared so configure and start the VPE... */
static int vpe_run(struct vpe * v)
{
	unsigned long flags, val, dmt_flag;
	struct vpe_notifications *n;
	unsigned int vpeflags;
	struct tc *t;

	/* check we are the Master VPE */
	local_irq_save(flags);
	val = read_c0_vpeconf0();
	if (!(val & VPECONF0_MVP)) {
		printk(KERN_WARNING
		       "VPE loader: only Master VPE's are allowed to configure MT\n");
		local_irq_restore(flags);

		return -1;
	}

	dmt_flag = dmt();
	vpeflags = dvpe();

	if (!list_empty(&v->tc)) {
		if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
			evpe(vpeflags);
			emt(dmt_flag);
			local_irq_restore(flags);

			printk(KERN_WARNING
			       "VPE loader: TC %d is already in use.\n",
                               t->index);
			return -ENOEXEC;
		}
	} else {
		evpe(vpeflags);
		emt(dmt_flag);
		local_irq_restore(flags);

		printk(KERN_WARNING
		       "VPE loader: No TC's associated with VPE %d\n",
		       v->minor);

		return -ENOEXEC;
	}

	/* Put MVPE's into 'configuration state' */
	set_c0_mvpcontrol(MVPCONTROL_VPC);

	settc(t->index);

	/* should check it is halted, and not activated */
	if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) {
		evpe(vpeflags);
		emt(dmt_flag);
		local_irq_restore(flags);

		printk(KERN_WARNING "VPE loader: TC %d is already active!\n",
		       t->index);

		return -ENOEXEC;
	}

	/* Write the address we want it to start running from in the TCPC register. */
	write_tc_c0_tcrestart((unsigned long)v->__start);
	write_tc_c0_tccontext((unsigned long)0);

	/*
	 * Mark the TC as activated, not interrupt exempt and not dynamically
	 * allocatable
	 */
	val = read_tc_c0_tcstatus();
	val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A;
	write_tc_c0_tcstatus(val);

	write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H);

	/*
	 * The sde-kit passes 'memsize' to __start in $a3, so set something
	 * here...  Or set $a3 to zero and define DFLT_STACK_SIZE and
	 * DFLT_HEAP_SIZE when you compile your program
	 */
	mttgpr(6, v->ntcs);
	mttgpr(7, physical_memsize);

	/* set up VPE1 */
	/*
	 * bind the TC to VPE 1 as late as possible so we only have the final
	 * VPE registers to set up, and so an EJTAG probe can trigger on it
	 */
	write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | 1);

	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~(VPECONF0_VPA));

	back_to_back_c0_hazard();

	/* Set up the XTC bit in vpeconf0 to point at our tc */
	write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC))
	                      | (t->index << VPECONF0_XTC_SHIFT));

	back_to_back_c0_hazard();

	/* enable this VPE */
	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA);

	/* clear out any left overs from a previous program */
	write_vpe_c0_status(0);
	write_vpe_c0_cause(0);

	/* take system out of configuration state */
	clear_c0_mvpcontrol(MVPCONTROL_VPC);

	/*
	 * SMTC/SMVP kernels manage VPE enable independently,
	 * but uniprocessor kernels need to turn it on, even
	 * if that wasn't the pre-dvpe() state.
	 */
#ifdef CONFIG_SMP
	evpe(vpeflags);
#else
	evpe(EVPE_ENABLE);
#endif
	emt(dmt_flag);
	local_irq_restore(flags);

	list_for_each_entry(n, &v->notify, list)
		n->start(minor);

	return 0;
}

static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs,
				      unsigned int symindex, const char *strtab,
				      struct module *mod)
{
	Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);

	for (i = 1; i < n; i++) {
		if (strcmp(strtab + sym[i].st_name, "__start") == 0) {
			v->__start = sym[i].st_value;
		}

		if (strcmp(strtab + sym[i].st_name, "vpe_shared") == 0) {
			v->shared_ptr = (void *)sym[i].st_value;
		}
	}

	if ( (v->__start == 0) || (v->shared_ptr == NULL))
		return -1;

	return 0;
}

/*
 * Allocates a VPE with some program code space(the load address), copies the
 * contents of the program (p)buffer performing relocatations/etc, free's it
 * when finished.
 */
static int vpe_elfload(struct vpe * v)
{
	Elf_Ehdr *hdr;
	Elf_Shdr *sechdrs;
	long err = 0;
	char *secstrings, *strtab = NULL;
	unsigned int len, i, symindex = 0, strindex = 0, relocate = 0;
	struct module mod;	// so we can re-use the relocations code

	memset(&mod, 0, sizeof(struct module));
	strcpy(mod.name, "VPE loader");

	hdr = (Elf_Ehdr *) v->pbuffer;
	len = v->plen;

	/* Sanity checks against insmoding binaries or wrong arch,
	   weird elf version */
	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0
	    || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC)
	    || !elf_check_arch(hdr)
	    || hdr->e_shentsize != sizeof(*sechdrs)) {
		printk(KERN_WARNING
		       "VPE loader: program wrong arch or weird elf version\n");

		return -ENOEXEC;
	}

	if (hdr->e_type == ET_REL)
		relocate = 1;

	if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) {
		printk(KERN_ERR "VPE loader: program length %u truncated\n",
		       len);

		return -ENOEXEC;
	}

	/* Convenience variables */
	sechdrs = (void *)hdr + hdr->e_shoff;
	secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
	sechdrs[0].sh_addr = 0;

	/* And these should exist, but gcc whinges if we don't init them */
	symindex = strindex = 0;

	if (relocate) {
		for (i = 1; i < hdr->e_shnum; i++) {
			if (sechdrs[i].sh_type != SHT_NOBITS
			    && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) {
				printk(KERN_ERR "VPE program length %u truncated\n",
				       len);
				return -ENOEXEC;
			}

			/* Mark all sections sh_addr with their address in the
			   temporary image. */
			sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;

			/* Internal symbols and strings. */
			if (sechdrs[i].sh_type == SHT_SYMTAB) {
				symindex = i;
				strindex = sechdrs[i].sh_link;
				strtab = (char *)hdr + sechdrs[strindex].sh_offset;
			}
		}
		layout_sections(&mod, hdr, sechdrs, secstrings);
	}

	v->load_addr = alloc_progmem(mod.core_size);
	if (!v->load_addr)
		return -ENOMEM;

	pr_info("VPE loader: loading to %p\n", v->load_addr);

	if (relocate) {
		for (i = 0; i < hdr->e_shnum; i++) {
			void *dest;

			if (!(sechdrs[i].sh_flags & SHF_ALLOC))
				continue;

			dest = v->load_addr + sechdrs[i].sh_entsize;

			if (sechdrs[i].sh_type != SHT_NOBITS)
				memcpy(dest, (void *)sechdrs[i].sh_addr,
				       sechdrs[i].sh_size);
			/* Update sh_addr to point to copy in image. */
			sechdrs[i].sh_addr = (unsigned long)dest;

			printk(KERN_DEBUG " section sh_name %s sh_addr 0x%x\n",
			       secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr);
		}

 		/* Fix up syms, so that st_value is a pointer to location. */
 		simplify_symbols(sechdrs, symindex, strtab, secstrings,
 				 hdr->e_shnum, &mod);

 		/* Now do relocations. */
 		for (i = 1; i < hdr->e_shnum; i++) {
 			const char *strtab = (char *)sechdrs[strindex].sh_addr;
 			unsigned int info = sechdrs[i].sh_info;

 			/* Not a valid relocation section? */
 			if (info >= hdr->e_shnum)
 				continue;

 			/* Don't bother with non-allocated sections */
 			if (!(sechdrs[info].sh_flags & SHF_ALLOC))
 				continue;

 			if (sechdrs[i].sh_type == SHT_REL)
 				err = apply_relocations(sechdrs, strtab, symindex, i,
 							&mod);
 			else if (sechdrs[i].sh_type == SHT_RELA)
 				err = apply_relocate_add(sechdrs, strtab, symindex, i,
 							 &mod);
 			if (err < 0)
 				return err;

  		}
  	} else {
		struct elf_phdr *phdr = (struct elf_phdr *) ((char *)hdr + hdr->e_phoff);

		for (i = 0; i < hdr->e_phnum; i++) {
			if (phdr->p_type == PT_LOAD) {
				memcpy((void *)phdr->p_paddr,
				       (char *)hdr + phdr->p_offset,
				       phdr->p_filesz);
				memset((void *)phdr->p_paddr + phdr->p_filesz,
				       0, phdr->p_memsz - phdr->p_filesz);
		    }
		    phdr++;
		}

		for (i = 0; i < hdr->e_shnum; i++) {
 			/* Internal symbols and strings. */
 			if (sechdrs[i].sh_type == SHT_SYMTAB) {
 				symindex = i;
 				strindex = sechdrs[i].sh_link;
 				strtab = (char *)hdr + sechdrs[strindex].sh_offset;

 				/* mark the symtab's address for when we try to find the
 				   magic symbols */
 				sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset;
 			}
		}
	}

	/* make sure it's physically written out */
	flush_icache_range((unsigned long)v->load_addr,
			   (unsigned long)v->load_addr + v->len);

	if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) {
		if (v->__start == 0) {
			printk(KERN_WARNING "VPE loader: program does not contain "
			       "a __start symbol\n");
			return -ENOEXEC;
		}

		if (v->shared_ptr == NULL)
			printk(KERN_WARNING "VPE loader: "
			       "program does not contain vpe_shared symbol.\n"
			       " Unable to use AMVP (AP/SP) facilities.\n");
	}

	printk(" elf loaded\n");
	return 0;
}

static void cleanup_tc(struct tc *tc)
{
	unsigned long flags;
	unsigned int mtflags, vpflags;
	int tmp;

	local_irq_save(flags);
	mtflags = dmt();
	vpflags = dvpe();
	/* Put MVPE's into 'configuration state' */
	set_c0_mvpcontrol(MVPCONTROL_VPC);

	settc(tc->index);
	tmp = read_tc_c0_tcstatus();

	/* mark not allocated and not dynamically allocatable */
	tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
	tmp |= TCSTATUS_IXMT;	/* interrupt exempt */
	write_tc_c0_tcstatus(tmp);

	write_tc_c0_tchalt(TCHALT_H);
	mips_ihb();

	/* bind it to anything other than VPE1 */
//	write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE

	clear_c0_mvpcontrol(MVPCONTROL_VPC);
	evpe(vpflags);
	emt(mtflags);
	local_irq_restore(flags);
}

static int getcwd(char *buff, int size)
{
	mm_segment_t old_fs;
	int ret;

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	ret = sys_getcwd(buff, size);

	set_fs(old_fs);

	return ret;
}

/* checks VPE is unused and gets ready to load program  */
static int vpe_open(struct inode *inode, struct file *filp)
{
	enum vpe_state state;
	struct vpe_notifications *not;
	struct vpe *v;
	int ret, err = 0;

	lock_kernel();
	if (minor != iminor(inode)) {
		/* assume only 1 device at the moment. */
		printk(KERN_WARNING "VPE loader: only vpe1 is supported\n");
		err = -ENODEV;
		goto out;
	}

	if ((v = get_vpe(tclimit)) == NULL) {
		printk(KERN_WARNING "VPE loader: unable to get vpe\n");
		err = -ENODEV;
		goto out;
	}

	state = xchg(&v->state, VPE_STATE_INUSE);
	if (state != VPE_STATE_UNUSED) {
		printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n");

		list_for_each_entry(not, &v->notify, list) {
			not->stop(tclimit);
		}

		release_progmem(v->load_addr);
		cleanup_tc(get_tc(tclimit));
	}

	/* this of-course trashes what was there before... */
	v->pbuffer = vmalloc(P_SIZE);
	v->plen = P_SIZE;
	v->load_addr = NULL;
	v->len = 0;

	v->uid = filp->f_cred->fsuid;
	v->gid = filp->f_cred->fsgid;

#ifdef CONFIG_MIPS_APSP_KSPD
	/* get kspd to tell us when a syscall_exit happens */
	if (!kspd_events_reqd) {
		kspd_notify(&kspd_events);
		kspd_events_reqd++;
	}
#endif

	v->cwd[0] = 0;
	ret = getcwd(v->cwd, VPE_PATH_MAX);
	if (ret < 0)
		printk(KERN_WARNING "VPE loader: open, getcwd returned %d\n", ret);

	v->shared_ptr = NULL;
	v->__start = 0;

out:
	unlock_kernel();
	return 0;
}

static int vpe_release(struct inode *inode, struct file *filp)
{
	struct vpe *v;
	Elf_Ehdr *hdr;
	int ret = 0;

	v = get_vpe(tclimit);
	if (v == NULL)
		return -ENODEV;

	hdr = (Elf_Ehdr *) v->pbuffer;
	if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) == 0) {
		if (vpe_elfload(v) >= 0) {
			vpe_run(v);
		} else {
 			printk(KERN_WARNING "VPE loader: ELF load failed.\n");
			ret = -ENOEXEC;
		}
	} else {
 		printk(KERN_WARNING "VPE loader: only elf files are supported\n");
		ret = -ENOEXEC;
	}

	/* It's good to be able to run the SP and if it chokes have a look at
	   the /dev/rt?. But if we reset the pointer to the shared struct we
	   lose what has happened. So perhaps if garbage is sent to the vpe
	   device, use it as a trigger for the reset. Hopefully a nice
	   executable will be along shortly. */
	if (ret < 0)
		v->shared_ptr = NULL;

	// cleanup any temp buffers
	if (v->pbuffer)
		vfree(v->pbuffer);
	v->plen = 0;
	return ret;
}

static ssize_t vpe_write(struct file *file, const char __user * buffer,
			 size_t count, loff_t * ppos)
{
	size_t ret = count;
	struct vpe *v;

	if (iminor(file->f_path.dentry->d_inode) != minor)
		return -ENODEV;

	v = get_vpe(tclimit);
	if (v == NULL)
		return -ENODEV;

	if (v->pbuffer == NULL) {
		printk(KERN_ERR "VPE loader: no buffer for program\n");
		return -ENOMEM;
	}

	if ((count + v->len) > v->plen) {
		printk(KERN_WARNING
		       "VPE loader: elf size too big. Perhaps strip uneeded symbols\n");
		return -ENOMEM;
	}

	count -= copy_from_user(v->pbuffer + v->len, buffer, count);
	if (!count)
		return -EFAULT;

	v->len += count;
	return ret;
}

static const struct file_operations vpe_fops = {
	.owner = THIS_MODULE,
	.open = vpe_open,
	.release = vpe_release,
	.write = vpe_write
};

/* module wrapper entry points */
/* give me a vpe */
vpe_handle vpe_alloc(void)
{
	int i;
	struct vpe *v;

	/* find a vpe */
	for (i = 1; i < MAX_VPES; i++) {
		if ((v = get_vpe(i)) != NULL) {
			v->state = VPE_STATE_INUSE;
			return v;
		}
	}
	return NULL;
}

EXPORT_SYMBOL(vpe_alloc);

/* start running from here */
int vpe_start(vpe_handle vpe, unsigned long start)
{
	struct vpe *v = vpe;

	v->__start = start;
	return vpe_run(v);
}

EXPORT_SYMBOL(vpe_start);

/* halt it for now */
int vpe_stop(vpe_handle vpe)
{
	struct vpe *v = vpe;
	struct tc *t;
	unsigned int evpe_flags;

	evpe_flags = dvpe();

	if ((t = list_entry(v->tc.next, struct tc, tc)) != NULL) {

		settc(t->index);
		write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);
	}

	evpe(evpe_flags);

	return 0;
}

EXPORT_SYMBOL(vpe_stop);

/* I've done with it thank you */
int vpe_free(vpe_handle vpe)
{
	struct vpe *v = vpe;
	struct tc *t;
	unsigned int evpe_flags;

	if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) {
		return -ENOEXEC;
	}

	evpe_flags = dvpe();

	/* Put MVPE's into 'configuration state' */
	set_c0_mvpcontrol(MVPCONTROL_VPC);

	settc(t->index);
	write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() & ~VPECONF0_VPA);

	/* halt the TC */
	write_tc_c0_tchalt(TCHALT_H);
	mips_ihb();

	/* mark the TC unallocated */
	write_tc_c0_tcstatus(read_tc_c0_tcstatus() & ~TCSTATUS_A);

	v->state = VPE_STATE_UNUSED;

	clear_c0_mvpcontrol(MVPCONTROL_VPC);
	evpe(evpe_flags);

	return 0;
}

EXPORT_SYMBOL(vpe_free);

void *vpe_get_shared(int index)
{
	struct vpe *v;

	if ((v = get_vpe(index)) == NULL)
		return NULL;

	return v->shared_ptr;
}

EXPORT_SYMBOL(vpe_get_shared);

int vpe_getuid(int index)
{
	struct vpe *v;

	if ((v = get_vpe(index)) == NULL)
		return -1;

	return v->uid;
}

EXPORT_SYMBOL(vpe_getuid);

int vpe_getgid(int index)
{
	struct vpe *v;

	if ((v = get_vpe(index)) == NULL)
		return -1;

	return v->gid;
}

EXPORT_SYMBOL(vpe_getgid);

int vpe_notify(int index, struct vpe_notifications *notify)
{
	struct vpe *v;

	if ((v = get_vpe(index)) == NULL)
		return -1;

	list_add(&notify->list, &v->notify);
	return 0;
}

EXPORT_SYMBOL(vpe_notify);

char *vpe_getcwd(int index)
{
	struct vpe *v;

	if ((v = get_vpe(index)) == NULL)
		return NULL;

	return v->cwd;
}

EXPORT_SYMBOL(vpe_getcwd);

#ifdef CONFIG_MIPS_APSP_KSPD
static void kspd_sp_exit( int sp_id)
{
	cleanup_tc(get_tc(sp_id));
}
#endif

static ssize_t store_kill(struct device *dev, struct device_attribute *attr,
			  const char *buf, size_t len)
{
	struct vpe *vpe = get_vpe(tclimit);
	struct vpe_notifications *not;

	list_for_each_entry(not, &vpe->notify, list) {
		not->stop(tclimit);
	}

	release_progmem(vpe->load_addr);
	cleanup_tc(get_tc(tclimit));
	vpe_stop(vpe);
	vpe_free(vpe);

	return len;
}

static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr,
			 char *buf)
{
	struct vpe *vpe = get_vpe(tclimit);

	return sprintf(buf, "%d\n", vpe->ntcs);
}

static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr,
			  const char *buf, size_t len)
{
	struct vpe *vpe = get_vpe(tclimit);
	unsigned long new;
	char *endp;

	new = simple_strtoul(buf, &endp, 0);
	if (endp == buf)
		goto out_einval;

	if (new == 0 || new > (hw_tcs - tclimit))
		goto out_einval;

	vpe->ntcs = new;

	return len;

out_einval:
	return -EINVAL;
}

static struct device_attribute vpe_class_attributes[] = {
	__ATTR(kill, S_IWUSR, NULL, store_kill),
	__ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs),
	{}
};

static void vpe_device_release(struct device *cd)
{
	kfree(cd);
}

struct class vpe_class = {
	.name = "vpe",
	.owner = THIS_MODULE,
	.dev_release = vpe_device_release,
	.dev_attrs = vpe_class_attributes,
};

struct device vpe_device;

static int __init vpe_module_init(void)
{
	unsigned int mtflags, vpflags;
	unsigned long flags, val;
	struct vpe *v = NULL;
	struct tc *t;
	int tc, err;

	if (!cpu_has_mipsmt) {
		printk("VPE loader: not a MIPS MT capable processor\n");
		return -ENODEV;
	}

	if (vpelimit == 0) {
		printk(KERN_WARNING "No VPEs reserved for AP/SP, not "
		       "initializing VPE loader.\nPass maxvpes=<n> argument as "
		       "kernel argument\n");

		return -ENODEV;
	}

	if (tclimit == 0) {
		printk(KERN_WARNING "No TCs reserved for AP/SP, not "
		       "initializing VPE loader.\nPass maxtcs=<n> argument as "
		       "kernel argument\n");

		return -ENODEV;
	}

	major = register_chrdev(0, module_name, &vpe_fops);
	if (major < 0) {
		printk("VPE loader: unable to register character device\n");
		return major;
	}

	err = class_register(&vpe_class);
	if (err) {
		printk(KERN_ERR "vpe_class registration failed\n");
		goto out_chrdev;
	}

	device_initialize(&vpe_device);
	vpe_device.class	= &vpe_class,
	vpe_device.parent	= NULL,
	dev_set_name(&vpe_device, "vpe1");
	vpe_device.devt = MKDEV(major, minor);
	err = device_add(&vpe_device);
	if (err) {
		printk(KERN_ERR "Adding vpe_device failed\n");
		goto out_class;
	}

	local_irq_save(flags);
	mtflags = dmt();
	vpflags = dvpe();

	/* Put MVPE's into 'configuration state' */
	set_c0_mvpcontrol(MVPCONTROL_VPC);

	/* dump_mtregs(); */

	val = read_c0_mvpconf0();
	hw_tcs = (val & MVPCONF0_PTC) + 1;
	hw_vpes = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1;

	for (tc = tclimit; tc < hw_tcs; tc++) {
		/*
		 * Must re-enable multithreading temporarily or in case we
		 * reschedule send IPIs or similar we might hang.
		 */
		clear_c0_mvpcontrol(MVPCONTROL_VPC);
		evpe(vpflags);
		emt(mtflags);
		local_irq_restore(flags);
		t = alloc_tc(tc);
		if (!t) {
			err = -ENOMEM;
			goto out;
		}

		local_irq_save(flags);
		mtflags = dmt();
		vpflags = dvpe();
		set_c0_mvpcontrol(MVPCONTROL_VPC);

		/* VPE's */
		if (tc < hw_tcs) {
			settc(tc);

			if ((v = alloc_vpe(tc)) == NULL) {
				printk(KERN_WARNING "VPE: unable to allocate VPE\n");

				goto out_reenable;
			}

			v->ntcs = hw_tcs - tclimit;

			/* add the tc to the list of this vpe's tc's. */
			list_add(&t->tc, &v->tc);

			/* deactivate all but vpe0 */
			if (tc >= tclimit) {
				unsigned long tmp = read_vpe_c0_vpeconf0();

				tmp &= ~VPECONF0_VPA;

				/* master VPE */
				tmp |= VPECONF0_MVP;
				write_vpe_c0_vpeconf0(tmp);
			}

			/* disable multi-threading with TC's */
			write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE);

			if (tc >= vpelimit) {
				/*
				 * Set config to be the same as vpe0,
				 * particularly kseg0 coherency alg
				 */
				write_vpe_c0_config(read_c0_config());
			}
		}

		/* TC's */
		t->pvpe = v;	/* set the parent vpe */

		if (tc >= tclimit) {
			unsigned long tmp;

			settc(tc);

			/* Any TC that is bound to VPE0 gets left as is - in case
			   we are running SMTC on VPE0. A TC that is bound to any
			   other VPE gets bound to VPE0, ideally I'd like to make
			   it homeless but it doesn't appear to let me bind a TC
			   to a non-existent VPE. Which is perfectly reasonable.

			   The (un)bound state is visible to an EJTAG probe so may
			   notify GDB...
			*/

			if (((tmp = read_tc_c0_tcbind()) & TCBIND_CURVPE)) {
				/* tc is bound >vpe0 */
				write_tc_c0_tcbind(tmp & ~TCBIND_CURVPE);

				t->pvpe = get_vpe(0);	/* set the parent vpe */
			}

			/* halt the TC */
			write_tc_c0_tchalt(TCHALT_H);
			mips_ihb();

			tmp = read_tc_c0_tcstatus();

			/* mark not activated and not dynamically allocatable */
			tmp &= ~(TCSTATUS_A | TCSTATUS_DA);
			tmp |= TCSTATUS_IXMT;	/* interrupt exempt */
			write_tc_c0_tcstatus(tmp);
		}
	}

out_reenable:
	/* release config state */
	clear_c0_mvpcontrol(MVPCONTROL_VPC);

	evpe(vpflags);
	emt(mtflags);
	local_irq_restore(flags);

#ifdef CONFIG_MIPS_APSP_KSPD
	kspd_events.kspd_sp_exit = kspd_sp_exit;
#endif
	return 0;

out_class:
	class_unregister(&vpe_class);
out_chrdev:
	unregister_chrdev(major, module_name);

out:
	return err;
}

static void __exit vpe_module_exit(void)
{
	struct vpe *v, *n;

	list_for_each_entry_safe(v, n, &vpecontrol.vpe_list, list) {
		if (v->state != VPE_STATE_UNUSED) {
			release_vpe(v);
		}
	}

	device_del(&vpe_device);
	unregister_chrdev(major, module_name);
}

module_init(vpe_module_init);
module_exit(vpe_module_exit);
MODULE_DESCRIPTION("MIPS VPE Loader");
MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc.");
MODULE_LICENSE("GPL");
