/*
 * Copyright 2010 Tilera Corporation. All Rights Reserved.
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   as published by the Free Software Foundation, version 2.
 *
 *   This program is distributed in the hope that it will be useful, but
 *   WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 *   NON INFRINGEMENT.  See the GNU General Public License for
 *   more details.
 *
 * Based on i386 version, copyright (C) 2001 Rusty Russell.
 */

#include <linux/moduleloader.h>
#include <linux/elf.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/kernel.h>
#include <asm/pgtable.h>
#include <asm/homecache.h>
#include <arch/opcode.h>

#ifdef __tilegx__
# define Elf_Rela Elf64_Rela
# define ELF_R_SYM ELF64_R_SYM
# define ELF_R_TYPE ELF64_R_TYPE
#else
# define Elf_Rela Elf32_Rela
# define ELF_R_SYM ELF32_R_SYM
# define ELF_R_TYPE ELF32_R_TYPE
#endif

#ifdef MODULE_DEBUG
#define DEBUGP printk
#else
#define DEBUGP(fmt...)
#endif

/*
 * Allocate some address space in the range MEM_MODULE_START to
 * MEM_MODULE_END and populate it with memory.
 */
void *module_alloc(unsigned long size)
{
	struct page **pages;
	pgprot_t prot_rwx = __pgprot(_PAGE_KERNEL | _PAGE_KERNEL_EXEC);
	struct vm_struct *area;
	int i = 0;
	int npages;

	if (size == 0)
		return NULL;
	npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
	pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
	if (pages == NULL)
		return NULL;
	for (; i < npages; ++i) {
		pages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
		if (!pages[i])
			goto error;
	}

	area = __get_vm_area(size, VM_ALLOC, MEM_MODULE_START, MEM_MODULE_END);
	if (!area)
		goto error;

	if (map_vm_area(area, prot_rwx, &pages)) {
		vunmap(area->addr);
		goto error;
	}

	return area->addr;

error:
	while (--i >= 0)
		__free_page(pages[i]);
	kfree(pages);
	return NULL;
}


/* Free memory returned from module_alloc */
void module_free(struct module *mod, void *module_region)
{
	vfree(module_region);

	/* Globally flush the L1 icache. */
	flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask,
		     0, 0, 0, NULL, NULL, 0);

	/*
	 * FIXME: If module_region == mod->module_init, trim exception
	 * table entries.
	 */
}

#ifdef __tilegx__
/*
 * Validate that the high 16 bits of "value" is just the sign-extension of
 * the low 48 bits.
 */
static int validate_hw2_last(long value, struct module *me)
{
	if (((value << 16) >> 16) != value) {
		pr_warning("module %s: Out of range HW2_LAST value %#lx\n",
			   me->name, value);
		return 0;
	}
	return 1;
}

/*
 * Validate that "value" isn't too big to hold in a JumpOff relocation.
 */
static int validate_jumpoff(long value)
{
	/* Determine size of jump offset. */
	int shift = __builtin_clzl(get_JumpOff_X1(create_JumpOff_X1(-1)));

	/* Check to see if it fits into the relocation slot. */
	long f = get_JumpOff_X1(create_JumpOff_X1(value));
	f = (f << shift) >> shift;

	return f == value;
}
#endif

int apply_relocate_add(Elf_Shdr *sechdrs,
		       const char *strtab,
		       unsigned int symindex,
		       unsigned int relsec,
		       struct module *me)
{
	unsigned int i;
	Elf_Rela *rel = (void *)sechdrs[relsec].sh_addr;
	Elf_Sym *sym;
	u64 *location;
	unsigned long value;

	DEBUGP("Applying relocate section %u to %u\n", relsec,
	       sechdrs[relsec].sh_info);
	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
		/* 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.
		 * Note that all undefined symbols have been resolved.
		 */
		sym = (Elf_Sym *)sechdrs[symindex].sh_addr
			+ ELF_R_SYM(rel[i].r_info);
		value = sym->st_value + rel[i].r_addend;

		switch (ELF_R_TYPE(rel[i].r_info)) {

#define MUNGE(func) (*location = ((*location & ~func(-1)) | func(value)))

#ifndef __tilegx__
		case R_TILE_32:
			*(uint32_t *)location = value;
			break;
		case R_TILE_IMM16_X0_HA:
			value = (value + 0x8000) >> 16;
			/*FALLTHROUGH*/
		case R_TILE_IMM16_X0_LO:
			MUNGE(create_Imm16_X0);
			break;
		case R_TILE_IMM16_X1_HA:
			value = (value + 0x8000) >> 16;
			/*FALLTHROUGH*/
		case R_TILE_IMM16_X1_LO:
			MUNGE(create_Imm16_X1);
			break;
		case R_TILE_JOFFLONG_X1:
			value -= (unsigned long) location;  /* pc-relative */
			value = (long) value >> 3;     /* count by instrs */
			MUNGE(create_JOffLong_X1);
			break;
#else
		case R_TILEGX_64:
			*location = value;
			break;
		case R_TILEGX_IMM16_X0_HW2_LAST:
			if (!validate_hw2_last(value, me))
				return -ENOEXEC;
			value >>= 16;
			/*FALLTHROUGH*/
		case R_TILEGX_IMM16_X0_HW1:
			value >>= 16;
			/*FALLTHROUGH*/
		case R_TILEGX_IMM16_X0_HW0:
			MUNGE(create_Imm16_X0);
			break;
		case R_TILEGX_IMM16_X1_HW2_LAST:
			if (!validate_hw2_last(value, me))
				return -ENOEXEC;
			value >>= 16;
			/*FALLTHROUGH*/
		case R_TILEGX_IMM16_X1_HW1:
			value >>= 16;
			/*FALLTHROUGH*/
		case R_TILEGX_IMM16_X1_HW0:
			MUNGE(create_Imm16_X1);
			break;
		case R_TILEGX_JUMPOFF_X1:
			value -= (unsigned long) location;  /* pc-relative */
			value = (long) value >> 3;     /* count by instrs */
			if (!validate_jumpoff(value)) {
				pr_warning("module %s: Out of range jump to"
					   " %#llx at %#llx (%p)\n", me->name,
					   sym->st_value + rel[i].r_addend,
					   rel[i].r_offset, location);
				return -ENOEXEC;
			}
			MUNGE(create_JumpOff_X1);
			break;
#endif

#undef MUNGE

		default:
			pr_err("module %s: Unknown relocation: %d\n",
			       me->name, (int) ELF_R_TYPE(rel[i].r_info));
			return -ENOEXEC;
		}
	}
	return 0;
}
