/*
 * cod.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * This module implements DSP code management for the DSP/BIOS Bridge
 * environment. It is mostly a thin wrapper.
 *
 * This module provides an interface for loading both static and
 * dynamic code objects onto DSP systems.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <linux/types.h>

/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- Trace & Debug */
#include <dspbridge/dbc.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/ldr.h>

/*  ----------------------------------- Platform Manager */
/* Include appropriate loader header file */
#include <dspbridge/dbll.h>

/*  ----------------------------------- This */
#include <dspbridge/cod.h>

/*
 *  ======== cod_manager ========
 */
struct cod_manager {
	struct dbll_tar_obj *target;
	struct dbll_library_obj *base_lib;
	bool loaded;		/* Base library loaded? */
	u32 ul_entry;
	struct ldr_module *dll_obj;
	struct dbll_fxns fxns;
	struct dbll_attrs attrs;
	char sz_zl_file[COD_MAXPATHLENGTH];
};

/*
 *  ======== cod_libraryobj ========
 */
struct cod_libraryobj {
	struct dbll_library_obj *dbll_lib;
	struct cod_manager *cod_mgr;
};

static u32 refs = 0L;

static struct dbll_fxns ldr_fxns = {
	(dbll_close_fxn) dbll_close,
	(dbll_create_fxn) dbll_create,
	(dbll_delete_fxn) dbll_delete,
	(dbll_exit_fxn) dbll_exit,
	(dbll_get_attrs_fxn) dbll_get_attrs,
	(dbll_get_addr_fxn) dbll_get_addr,
	(dbll_get_c_addr_fxn) dbll_get_c_addr,
	(dbll_get_sect_fxn) dbll_get_sect,
	(dbll_init_fxn) dbll_init,
	(dbll_load_fxn) dbll_load,
	(dbll_load_sect_fxn) dbll_load_sect,
	(dbll_open_fxn) dbll_open,
	(dbll_read_sect_fxn) dbll_read_sect,
	(dbll_set_attrs_fxn) dbll_set_attrs,
	(dbll_unload_fxn) dbll_unload,
	(dbll_unload_sect_fxn) dbll_unload_sect,
};

static bool no_op(void);

/*
 * File operations (originally were under kfile.c)
 */
static s32 cod_f_close(struct file *filp)
{
	/* Check for valid handle */
	if (!filp)
		return -EFAULT;

	filp_close(filp, NULL);

	/* we can't use 0 here */
	return 0;
}

static struct file *cod_f_open(const char *psz_file_name, const char *sz_mode)
{
	mm_segment_t fs;
	struct file *filp;

	fs = get_fs();
	set_fs(get_ds());

	/* ignore given mode and open file as read-only */
	filp = filp_open(psz_file_name, O_RDONLY, 0);

	if (IS_ERR(filp))
		filp = NULL;

	set_fs(fs);

	return filp;
}

static s32 cod_f_read(void __user *pbuffer, s32 size, s32 count,
		      struct file *filp)
{
	/* check for valid file handle */
	if (!filp)
		return -EFAULT;

	if ((size > 0) && (count > 0) && pbuffer) {
		u32 dw_bytes_read;
		mm_segment_t fs;

		/* read from file */
		fs = get_fs();
		set_fs(get_ds());
		dw_bytes_read = filp->f_op->read(filp, pbuffer, size * count,
						 &(filp->f_pos));
		set_fs(fs);

		if (!dw_bytes_read)
			return -EBADF;

		return dw_bytes_read / size;
	}

	return -EINVAL;
}

static s32 cod_f_seek(struct file *filp, s32 offset, s32 origin)
{
	loff_t dw_cur_pos;

	/* check for valid file handle */
	if (!filp)
		return -EFAULT;

	/* based on the origin flag, move the internal pointer */
	dw_cur_pos = filp->f_op->llseek(filp, offset, origin);

	if ((s32) dw_cur_pos < 0)
		return -EPERM;

	/* we can't use 0 here */
	return 0;
}

static s32 cod_f_tell(struct file *filp)
{
	loff_t dw_cur_pos;

	if (!filp)
		return -EFAULT;

	/* Get current position */
	dw_cur_pos = filp->f_op->llseek(filp, 0, SEEK_CUR);

	if ((s32) dw_cur_pos < 0)
		return -EPERM;

	return dw_cur_pos;
}

/*
 *  ======== cod_close ========
 */
void cod_close(struct cod_libraryobj *lib)
{
	struct cod_manager *hmgr;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(lib != NULL);
	DBC_REQUIRE(lib->cod_mgr);

	hmgr = lib->cod_mgr;
	hmgr->fxns.close_fxn(lib->dbll_lib);

	kfree(lib);
}

/*
 *  ======== cod_create ========
 *  Purpose:
 *      Create an object to manage code on a DSP system.
 *      This object can be used to load an initial program image with
 *      arguments that can later be expanded with
 *      dynamically loaded object files.
 *
 */
int cod_create(struct cod_manager **mgr, char *str_zl_file,
		      const struct cod_attrs *attrs)
{
	struct cod_manager *mgr_new;
	struct dbll_attrs zl_attrs;
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(mgr != NULL);

	/* assume failure */
	*mgr = NULL;

	/* we don't support non-default attrs yet */
	if (attrs != NULL)
		return -ENOSYS;

	mgr_new = kzalloc(sizeof(struct cod_manager), GFP_KERNEL);
	if (mgr_new == NULL)
		return -ENOMEM;

	/* Set up loader functions */
	mgr_new->fxns = ldr_fxns;

	/* initialize the ZL module */
	mgr_new->fxns.init_fxn();

	zl_attrs.alloc = (dbll_alloc_fxn) no_op;
	zl_attrs.free = (dbll_free_fxn) no_op;
	zl_attrs.fread = (dbll_read_fxn) cod_f_read;
	zl_attrs.fseek = (dbll_seek_fxn) cod_f_seek;
	zl_attrs.ftell = (dbll_tell_fxn) cod_f_tell;
	zl_attrs.fclose = (dbll_f_close_fxn) cod_f_close;
	zl_attrs.fopen = (dbll_f_open_fxn) cod_f_open;
	zl_attrs.sym_lookup = NULL;
	zl_attrs.base_image = true;
	zl_attrs.log_write = NULL;
	zl_attrs.log_write_handle = NULL;
	zl_attrs.write = NULL;
	zl_attrs.rmm_handle = NULL;
	zl_attrs.input_params = NULL;
	zl_attrs.sym_handle = NULL;
	zl_attrs.sym_arg = NULL;

	mgr_new->attrs = zl_attrs;

	status = mgr_new->fxns.create_fxn(&mgr_new->target, &zl_attrs);

	if (status) {
		cod_delete(mgr_new);
		return -ESPIPE;
	}

	/* return the new manager */
	*mgr = mgr_new;

	return 0;
}

/*
 *  ======== cod_delete ========
 *  Purpose:
 *      Delete a code manager object.
 */
void cod_delete(struct cod_manager *cod_mgr_obj)
{
	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(cod_mgr_obj);

	if (cod_mgr_obj->base_lib) {
		if (cod_mgr_obj->loaded)
			cod_mgr_obj->fxns.unload_fxn(cod_mgr_obj->base_lib,
							&cod_mgr_obj->attrs);

		cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);
	}
	if (cod_mgr_obj->target) {
		cod_mgr_obj->fxns.delete_fxn(cod_mgr_obj->target);
		cod_mgr_obj->fxns.exit_fxn();
	}
	kfree(cod_mgr_obj);
}

/*
 *  ======== cod_exit ========
 *  Purpose:
 *      Discontinue usage of the COD module.
 *
 */
void cod_exit(void)
{
	DBC_REQUIRE(refs > 0);

	refs--;

	DBC_ENSURE(refs >= 0);
}

/*
 *  ======== cod_get_base_lib ========
 *  Purpose:
 *      Get handle to the base image DBL library.
 */
int cod_get_base_lib(struct cod_manager *cod_mgr_obj,
			    struct dbll_library_obj **plib)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(cod_mgr_obj);
	DBC_REQUIRE(plib != NULL);

	*plib = (struct dbll_library_obj *)cod_mgr_obj->base_lib;

	return status;
}

/*
 *  ======== cod_get_base_name ========
 */
int cod_get_base_name(struct cod_manager *cod_mgr_obj, char *sz_name,
			     u32 usize)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(cod_mgr_obj);
	DBC_REQUIRE(sz_name != NULL);

	if (usize <= COD_MAXPATHLENGTH)
		strncpy(sz_name, cod_mgr_obj->sz_zl_file, usize);
	else
		status = -EPERM;

	return status;
}

/*
 *  ======== cod_get_entry ========
 *  Purpose:
 *      Retrieve the entry point of a loaded DSP program image
 *
 */
int cod_get_entry(struct cod_manager *cod_mgr_obj, u32 *entry_pt)
{
	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(cod_mgr_obj);
	DBC_REQUIRE(entry_pt != NULL);

	*entry_pt = cod_mgr_obj->ul_entry;

	return 0;
}

/*
 *  ======== cod_get_loader ========
 *  Purpose:
 *      Get handle to the DBLL loader.
 */
int cod_get_loader(struct cod_manager *cod_mgr_obj,
			  struct dbll_tar_obj **loader)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(cod_mgr_obj);
	DBC_REQUIRE(loader != NULL);

	*loader = (struct dbll_tar_obj *)cod_mgr_obj->target;

	return status;
}

/*
 *  ======== cod_get_section ========
 *  Purpose:
 *      Retrieve the starting address and length of a section in the COFF file
 *      given the section name.
 */
int cod_get_section(struct cod_libraryobj *lib, char *str_sect,
			   u32 *addr, u32 *len)
{
	struct cod_manager *cod_mgr_obj;
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(lib != NULL);
	DBC_REQUIRE(lib->cod_mgr);
	DBC_REQUIRE(str_sect != NULL);
	DBC_REQUIRE(addr != NULL);
	DBC_REQUIRE(len != NULL);

	*addr = 0;
	*len = 0;
	if (lib != NULL) {
		cod_mgr_obj = lib->cod_mgr;
		status = cod_mgr_obj->fxns.get_sect_fxn(lib->dbll_lib, str_sect,
							addr, len);
	} else {
		status = -ESPIPE;
	}

	DBC_ENSURE(!status || ((*addr == 0) && (*len == 0)));

	return status;
}

/*
 *  ======== cod_get_sym_value ========
 *  Purpose:
 *      Retrieve the value for the specified symbol. The symbol is first
 *      searched for literally and then, if not found, searched for as a
 *      C symbol.
 *
 */
int cod_get_sym_value(struct cod_manager *cod_mgr_obj, char *str_sym,
			     u32 *pul_value)
{
	struct dbll_sym_val *dbll_sym;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(cod_mgr_obj);
	DBC_REQUIRE(str_sym != NULL);
	DBC_REQUIRE(pul_value != NULL);

	dev_dbg(bridge, "%s: cod_mgr_obj: %p str_sym: %s pul_value: %p\n",
		__func__, cod_mgr_obj, str_sym, pul_value);
	if (cod_mgr_obj->base_lib) {
		if (!cod_mgr_obj->fxns.
		    get_addr_fxn(cod_mgr_obj->base_lib, str_sym, &dbll_sym)) {
			if (!cod_mgr_obj->fxns.
			    get_c_addr_fxn(cod_mgr_obj->base_lib, str_sym,
						&dbll_sym))
				return -ESPIPE;
		}
	} else {
		return -ESPIPE;
	}

	*pul_value = dbll_sym->value;

	return 0;
}

/*
 *  ======== cod_init ========
 *  Purpose:
 *      Initialize the COD module's private state.
 *
 */
bool cod_init(void)
{
	bool ret = true;

	DBC_REQUIRE(refs >= 0);

	if (ret)
		refs++;

	DBC_ENSURE((ret && refs > 0) || (!ret && refs >= 0));
	return ret;
}

/*
 *  ======== cod_load_base ========
 *  Purpose:
 *      Load the initial program image, optionally with command-line arguments,
 *      on the DSP system managed by the supplied handle. The program to be
 *      loaded must be the first element of the args array and must be a fully
 *      qualified pathname.
 *  Details:
 *      if num_argc doesn't match the number of arguments in the args array, the
 *      args array is searched for a NULL terminating entry, and argc is
 *      recalculated to reflect this.  In this way, we can support NULL
 *      terminating args arrays, if num_argc is very large.
 */
int cod_load_base(struct cod_manager *cod_mgr_obj, u32 num_argc, char *args[],
			 cod_writefxn pfn_write, void *arb, char *envp[])
{
	dbll_flags flags;
	struct dbll_attrs save_attrs;
	struct dbll_attrs new_attrs;
	int status;
	u32 i;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(cod_mgr_obj);
	DBC_REQUIRE(num_argc > 0);
	DBC_REQUIRE(args != NULL);
	DBC_REQUIRE(args[0] != NULL);
	DBC_REQUIRE(pfn_write != NULL);
	DBC_REQUIRE(cod_mgr_obj->base_lib != NULL);

	/*
	 *  Make sure every argv[] stated in argc has a value, or change argc to
	 *  reflect true number in NULL terminated argv array.
	 */
	for (i = 0; i < num_argc; i++) {
		if (args[i] == NULL) {
			num_argc = i;
			break;
		}
	}

	/* set the write function for this operation */
	cod_mgr_obj->fxns.get_attrs_fxn(cod_mgr_obj->target, &save_attrs);

	new_attrs = save_attrs;
	new_attrs.write = (dbll_write_fxn) pfn_write;
	new_attrs.input_params = arb;
	new_attrs.alloc = (dbll_alloc_fxn) no_op;
	new_attrs.free = (dbll_free_fxn) no_op;
	new_attrs.log_write = NULL;
	new_attrs.log_write_handle = NULL;

	/* Load the image */
	flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
	status = cod_mgr_obj->fxns.load_fxn(cod_mgr_obj->base_lib, flags,
					    &new_attrs,
					    &cod_mgr_obj->ul_entry);
	if (status)
		cod_mgr_obj->fxns.close_fxn(cod_mgr_obj->base_lib);

	if (!status)
		cod_mgr_obj->loaded = true;
	else
		cod_mgr_obj->base_lib = NULL;

	return status;
}

/*
 *  ======== cod_open ========
 *      Open library for reading sections.
 */
int cod_open(struct cod_manager *hmgr, char *sz_coff_path,
		    u32 flags, struct cod_libraryobj **lib_obj)
{
	int status = 0;
	struct cod_libraryobj *lib = NULL;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(hmgr);
	DBC_REQUIRE(sz_coff_path != NULL);
	DBC_REQUIRE(flags == COD_NOLOAD || flags == COD_SYMB);
	DBC_REQUIRE(lib_obj != NULL);

	*lib_obj = NULL;

	lib = kzalloc(sizeof(struct cod_libraryobj), GFP_KERNEL);
	if (lib == NULL)
		status = -ENOMEM;

	if (!status) {
		lib->cod_mgr = hmgr;
		status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags,
					     &lib->dbll_lib);
		if (!status)
			*lib_obj = lib;
	}

	if (status)
		pr_err("%s: error status 0x%x, sz_coff_path: %s flags: 0x%x\n",
		       __func__, status, sz_coff_path, flags);
	return status;
}

/*
 *  ======== cod_open_base ========
 *  Purpose:
 *      Open base image for reading sections.
 */
int cod_open_base(struct cod_manager *hmgr, char *sz_coff_path,
			 dbll_flags flags)
{
	int status = 0;
	struct dbll_library_obj *lib;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(hmgr);
	DBC_REQUIRE(sz_coff_path != NULL);

	/* if we previously opened a base image, close it now */
	if (hmgr->base_lib) {
		if (hmgr->loaded) {
			hmgr->fxns.unload_fxn(hmgr->base_lib, &hmgr->attrs);
			hmgr->loaded = false;
		}
		hmgr->fxns.close_fxn(hmgr->base_lib);
		hmgr->base_lib = NULL;
	}
	status = hmgr->fxns.open_fxn(hmgr->target, sz_coff_path, flags, &lib);
	if (!status) {
		/* hang onto the library for subsequent sym table usage */
		hmgr->base_lib = lib;
		strncpy(hmgr->sz_zl_file, sz_coff_path, COD_MAXPATHLENGTH - 1);
		hmgr->sz_zl_file[COD_MAXPATHLENGTH - 1] = '\0';
	}

	if (status)
		pr_err("%s: error status 0x%x sz_coff_path: %s\n", __func__,
		       status, sz_coff_path);
	return status;
}

/*
 *  ======== cod_read_section ========
 *  Purpose:
 *      Retrieve the content of a code section given the section name.
 */
int cod_read_section(struct cod_libraryobj *lib, char *str_sect,
			    char *str_content, u32 content_size)
{
	int status = 0;

	DBC_REQUIRE(refs > 0);
	DBC_REQUIRE(lib != NULL);
	DBC_REQUIRE(lib->cod_mgr);
	DBC_REQUIRE(str_sect != NULL);
	DBC_REQUIRE(str_content != NULL);

	if (lib != NULL)
		status =
		    lib->cod_mgr->fxns.read_sect_fxn(lib->dbll_lib, str_sect,
						     str_content, content_size);
	else
		status = -ESPIPE;

	return status;
}

/*
 *  ======== no_op ========
 *  Purpose:
 *      No Operation.
 *
 */
static bool no_op(void)
{
	return true;
}
