summaryrefslogtreecommitdiff
path: root/drivers/staging/tidspbridge/pmgr/dbll.c
diff options
context:
space:
mode:
authorKristina Martšenko <kristina.martsenko@gmail.com>2014-07-16 03:30:18 +0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-16 08:01:05 +0400
commitf190be7f39a5e480ddc5e0f49bbe670feb328c32 (patch)
tree3f9e857d94f4a95166b25ba049d91a2fa78d90a1 /drivers/staging/tidspbridge/pmgr/dbll.c
parentcb3aadaec89109edb60d4829ce82e50b27cb4ce6 (diff)
downloadlinux-f190be7f39a5e480ddc5e0f49bbe670feb328c32.tar.xz
staging: tidspbridge: remove driver
The driver has been broken and disabled for several kernel versions now. It doesn't have a maintainer anymore, and most of the people who've worked on it have moved on. There's also still a long list of issues in the TODO file before it can be moved out of staging. Until someone can put in the work to make the driver work again and move it out of staging, remove it from the kernel. Signed-off-by: Kristina Martšenko <kristina.martsenko@gmail.com> Cc: Omar Ramirez Luna <omar.ramirez@copitl.com> Cc: Suman Anna <s-anna@ti.com> Cc: Felipe Contreras <felipe.contreras@gmail.com> Cc: Ohad Ben-Cohen <ohad@wizery.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/tidspbridge/pmgr/dbll.c')
-rw-r--r--drivers/staging/tidspbridge/pmgr/dbll.c1421
1 files changed, 0 insertions, 1421 deletions
diff --git a/drivers/staging/tidspbridge/pmgr/dbll.c b/drivers/staging/tidspbridge/pmgr/dbll.c
deleted file mode 100644
index 8e21d1e47c9c..000000000000
--- a/drivers/staging/tidspbridge/pmgr/dbll.c
+++ /dev/null
@@ -1,1421 +0,0 @@
-/*
- * dbll.c
- *
- * DSP-BIOS Bridge driver support functions for TI OMAP processors.
- *
- * 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>
-
-/* ----------------------------------- DSP/BIOS Bridge */
-#include <dspbridge/dbdefs.h>
-
-#include <dspbridge/gh.h>
-
-/* ----------------------------------- OS Adaptation Layer */
-
-/* Dynamic loader library interface */
-#include <dspbridge/dynamic_loader.h>
-#include <dspbridge/getsection.h>
-
-/* ----------------------------------- This */
-#include <dspbridge/dbll.h>
-#include <dspbridge/rmm.h>
-
-/* Max buffer length */
-#define MAXEXPR 128
-
-#define DOFF_ALIGN(x) (((x) + 3) & ~3UL)
-
-/*
- * ======== struct dbll_tar_obj* ========
- * A target may have one or more libraries of symbols/code/data loaded
- * onto it, where a library is simply the symbols/code/data contained
- * in a DOFF file.
- */
-/*
- * ======== dbll_tar_obj ========
- */
-struct dbll_tar_obj {
- struct dbll_attrs attrs;
- struct dbll_library_obj *head; /* List of all opened libraries */
-};
-
-/*
- * The following 4 typedefs are "super classes" of the dynamic loader
- * library types used in dynamic loader functions (dynamic_loader.h).
- */
-/*
- * ======== dbll_stream ========
- * Contains dynamic_loader_stream
- */
-struct dbll_stream {
- struct dynamic_loader_stream dl_stream;
- struct dbll_library_obj *lib;
-};
-
-/*
- * ======== ldr_symbol ========
- */
-struct ldr_symbol {
- struct dynamic_loader_sym dl_symbol;
- struct dbll_library_obj *lib;
-};
-
-/*
- * ======== dbll_alloc ========
- */
-struct dbll_alloc {
- struct dynamic_loader_allocate dl_alloc;
- struct dbll_library_obj *lib;
-};
-
-/*
- * ======== dbll_init_obj ========
- */
-struct dbll_init_obj {
- struct dynamic_loader_initialize dl_init;
- struct dbll_library_obj *lib;
-};
-
-/*
- * ======== DBLL_Library ========
- * A library handle is returned by DBLL_Open() and is passed to dbll_load()
- * to load symbols/code/data, and to dbll_unload(), to remove the
- * symbols/code/data loaded by dbll_load().
- */
-
-/*
- * ======== dbll_library_obj ========
- */
-struct dbll_library_obj {
- struct dbll_library_obj *next; /* Next library in target's list */
- struct dbll_library_obj *prev; /* Previous in the list */
- struct dbll_tar_obj *target_obj; /* target for this library */
-
- /* Objects needed by dynamic loader */
- struct dbll_stream stream;
- struct ldr_symbol symbol;
- struct dbll_alloc allocate;
- struct dbll_init_obj init;
- void *dload_mod_obj;
-
- char *file_name; /* COFF file name */
- void *fp; /* Opaque file handle */
- u32 entry; /* Entry point */
- void *desc; /* desc of DOFF file loaded */
- u32 open_ref; /* Number of times opened */
- u32 load_ref; /* Number of times loaded */
- struct gh_t_hash_tab *sym_tab; /* Hash table of symbols */
- u32 pos;
-};
-
-/*
- * ======== dbll_symbol ========
- */
-struct dbll_symbol {
- struct dbll_sym_val value;
- char *name;
-};
-
-static void dof_close(struct dbll_library_obj *zl_lib);
-static int dof_open(struct dbll_library_obj *zl_lib);
-static s32 no_op(struct dynamic_loader_initialize *thisptr, void *bufr,
- ldr_addr locn, struct ldr_section_info *info,
- unsigned bytsize);
-
-/*
- * Functions called by dynamic loader
- *
- */
-/* dynamic_loader_stream */
-static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer,
- unsigned bufsize);
-static int dbll_set_file_posn(struct dynamic_loader_stream *this,
- unsigned int pos);
-/* dynamic_loader_sym */
-static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
- const char *name);
-static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym
- *this, const char *name,
- unsigned module_id);
-static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym
- *this, const char *name,
- unsigned moduleid);
-static void dbll_purge_symbol_table(struct dynamic_loader_sym *this,
- unsigned module_id);
-static void *allocate(struct dynamic_loader_sym *this, unsigned memsize);
-static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr);
-static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr,
- va_list args);
-/* dynamic_loader_allocate */
-static int dbll_rmm_alloc(struct dynamic_loader_allocate *this,
- struct ldr_section_info *info, unsigned align);
-static void rmm_dealloc(struct dynamic_loader_allocate *this,
- struct ldr_section_info *info);
-
-/* dynamic_loader_initialize */
-static int connect(struct dynamic_loader_initialize *this);
-static int read_mem(struct dynamic_loader_initialize *this, void *buf,
- ldr_addr addr, struct ldr_section_info *info,
- unsigned bytes);
-static int write_mem(struct dynamic_loader_initialize *this, void *buf,
- ldr_addr addr, struct ldr_section_info *info,
- unsigned nbytes);
-static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr,
- struct ldr_section_info *info, unsigned bytes,
- unsigned val);
-static int execute(struct dynamic_loader_initialize *this, ldr_addr start);
-static void release(struct dynamic_loader_initialize *this);
-
-/* symbol table hash functions */
-static u32 name_hash(const void *key);
-static bool name_match(const void *key, const void *sp);
-static void sym_delete(void *value);
-
-/* Symbol Redefinition */
-static int redefined_symbol;
-static int gbl_search = 1;
-
-/*
- * ======== dbll_close ========
- */
-void dbll_close(struct dbll_library_obj *zl_lib)
-{
- struct dbll_tar_obj *zl_target;
-
- zl_target = zl_lib->target_obj;
- zl_lib->open_ref--;
- if (zl_lib->open_ref == 0) {
- /* Remove library from list */
- if (zl_target->head == zl_lib)
- zl_target->head = zl_lib->next;
-
- if (zl_lib->prev)
- (zl_lib->prev)->next = zl_lib->next;
-
- if (zl_lib->next)
- (zl_lib->next)->prev = zl_lib->prev;
-
- /* Free DOF resources */
- dof_close(zl_lib);
- kfree(zl_lib->file_name);
-
- /* remove symbols from symbol table */
- if (zl_lib->sym_tab)
- gh_delete(zl_lib->sym_tab);
-
- /* remove the library object itself */
- kfree(zl_lib);
- zl_lib = NULL;
- }
-}
-
-/*
- * ======== dbll_create ========
- */
-int dbll_create(struct dbll_tar_obj **target_obj,
- struct dbll_attrs *pattrs)
-{
- struct dbll_tar_obj *pzl_target;
- int status = 0;
-
- /* Allocate DBL target object */
- pzl_target = kzalloc(sizeof(struct dbll_tar_obj), GFP_KERNEL);
- if (target_obj != NULL) {
- if (pzl_target == NULL) {
- *target_obj = NULL;
- status = -ENOMEM;
- } else {
- pzl_target->attrs = *pattrs;
- *target_obj = (struct dbll_tar_obj *)pzl_target;
- }
- }
-
- return status;
-}
-
-/*
- * ======== dbll_delete ========
- */
-void dbll_delete(struct dbll_tar_obj *target)
-{
- struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
-
- kfree(zl_target);
-
-}
-
-/*
- * ======== dbll_exit ========
- * Discontinue usage of DBL module.
- */
-void dbll_exit(void)
-{
- /* do nothing */
-}
-
-/*
- * ======== dbll_get_addr ========
- * Get address of name in the specified library.
- */
-bool dbll_get_addr(struct dbll_library_obj *zl_lib, char *name,
- struct dbll_sym_val **sym_val)
-{
- struct dbll_symbol *sym;
-
- sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, name);
- if (IS_ERR(sym))
- return false;
-
- *sym_val = &sym->value;
-
- dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p\n",
- __func__, zl_lib, name, sym_val);
- return true;
-}
-
-/*
- * ======== dbll_get_attrs ========
- * Retrieve the attributes of the target.
- */
-void dbll_get_attrs(struct dbll_tar_obj *target, struct dbll_attrs *pattrs)
-{
- struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
-
- if ((pattrs != NULL) && (zl_target != NULL))
- *pattrs = zl_target->attrs;
-
-}
-
-/*
- * ======== dbll_get_c_addr ========
- * Get address of a "C" name in the specified library.
- */
-bool dbll_get_c_addr(struct dbll_library_obj *zl_lib, char *name,
- struct dbll_sym_val **sym_val)
-{
- struct dbll_symbol *sym;
- char cname[MAXEXPR + 1];
-
- cname[0] = '_';
-
- strncpy(cname + 1, name, sizeof(cname) - 2);
- cname[MAXEXPR] = '\0'; /* insure '\0' string termination */
-
- /* Check for C name, if not found */
- sym = (struct dbll_symbol *)gh_find(zl_lib->sym_tab, cname);
- if (IS_ERR(sym))
- return false;
-
- *sym_val = &sym->value;
-
- return true;
-}
-
-/*
- * ======== dbll_get_sect ========
- * Get the base address and size (in bytes) of a COFF section.
- */
-int dbll_get_sect(struct dbll_library_obj *lib, char *name, u32 *paddr,
- u32 *psize)
-{
- u32 byte_size;
- bool opened_doff = false;
- const struct ldr_section_info *sect = NULL;
- struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
- int status = 0;
-
- /* If DOFF file is not open, we open it. */
- if (zl_lib != NULL) {
- if (zl_lib->fp == NULL) {
- status = dof_open(zl_lib);
- if (!status)
- opened_doff = true;
-
- } else {
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
- zl_lib->pos,
- SEEK_SET);
- }
- } else {
- status = -EFAULT;
- }
- if (!status) {
- byte_size = 1;
- if (dload_get_section_info(zl_lib->desc, name, &sect)) {
- *paddr = sect->load_addr;
- *psize = sect->size * byte_size;
- /* Make sure size is even for good swap */
- if (*psize % 2)
- (*psize)++;
-
- /* Align size */
- *psize = DOFF_ALIGN(*psize);
- } else {
- status = -ENXIO;
- }
- }
- if (opened_doff) {
- dof_close(zl_lib);
- opened_doff = false;
- }
-
- dev_dbg(bridge, "%s: lib: %p name: %s paddr: %p psize: %p, status 0x%x\n",
- __func__, lib, name, paddr, psize, status);
-
- return status;
-}
-
-/*
- * ======== dbll_init ========
- */
-bool dbll_init(void)
-{
- /* do nothing */
-
- return true;
-}
-
-/*
- * ======== dbll_load ========
- */
-int dbll_load(struct dbll_library_obj *lib, dbll_flags flags,
- struct dbll_attrs *attrs, u32 *entry)
-{
- struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
- struct dbll_tar_obj *dbzl;
- bool got_symbols = true;
- s32 err;
- int status = 0;
- bool opened_doff = false;
-
- /*
- * Load if not already loaded.
- */
- if (zl_lib->load_ref == 0 || !(flags & DBLL_DYNAMIC)) {
- dbzl = zl_lib->target_obj;
- dbzl->attrs = *attrs;
- /* Create a hash table for symbols if not already created */
- if (zl_lib->sym_tab == NULL) {
- got_symbols = false;
- zl_lib->sym_tab = gh_create(sizeof(struct dbll_symbol),
- name_hash,
- name_match, sym_delete);
- if (IS_ERR(zl_lib->sym_tab)) {
- status = PTR_ERR(zl_lib->sym_tab);
- zl_lib->sym_tab = NULL;
- }
-
- }
- /*
- * Set up objects needed by the dynamic loader
- */
- /* Stream */
- zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer;
- zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn;
- zl_lib->stream.lib = zl_lib;
- /* Symbol */
- zl_lib->symbol.dl_symbol.find_matching_symbol =
- dbll_find_symbol;
- if (got_symbols) {
- zl_lib->symbol.dl_symbol.add_to_symbol_table =
- find_in_symbol_table;
- } else {
- zl_lib->symbol.dl_symbol.add_to_symbol_table =
- dbll_add_to_symbol_table;
- }
- zl_lib->symbol.dl_symbol.purge_symbol_table =
- dbll_purge_symbol_table;
- zl_lib->symbol.dl_symbol.dload_allocate = allocate;
- zl_lib->symbol.dl_symbol.dload_deallocate = deallocate;
- zl_lib->symbol.dl_symbol.error_report = dbll_err_report;
- zl_lib->symbol.lib = zl_lib;
- /* Allocate */
- zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc;
- zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc;
- zl_lib->allocate.lib = zl_lib;
- /* Init */
- zl_lib->init.dl_init.connect = connect;
- zl_lib->init.dl_init.readmem = read_mem;
- zl_lib->init.dl_init.writemem = write_mem;
- zl_lib->init.dl_init.fillmem = fill_mem;
- zl_lib->init.dl_init.execute = execute;
- zl_lib->init.dl_init.release = release;
- zl_lib->init.lib = zl_lib;
- /* If COFF file is not open, we open it. */
- if (zl_lib->fp == NULL) {
- status = dof_open(zl_lib);
- if (!status)
- opened_doff = true;
-
- }
- if (!status) {
- zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell))
- (zl_lib->fp);
- /* Reset file cursor */
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
- (long)0,
- SEEK_SET);
- symbols_reloaded = true;
- /* The 5th argument, DLOAD_INITBSS, tells the DLL
- * module to zero-init all BSS sections. In general,
- * this is not necessary and also increases load time.
- * We may want to make this configurable by the user */
- err = dynamic_load_module(&zl_lib->stream.dl_stream,
- &zl_lib->symbol.dl_symbol,
- &zl_lib->allocate.dl_alloc,
- &zl_lib->init.dl_init,
- DLOAD_INITBSS,
- &zl_lib->dload_mod_obj);
-
- if (err != 0) {
- status = -EILSEQ;
- } else if (redefined_symbol) {
- zl_lib->load_ref++;
- dbll_unload(zl_lib, (struct dbll_attrs *)attrs);
- redefined_symbol = false;
- status = -EILSEQ;
- } else {
- *entry = zl_lib->entry;
- }
- }
- }
- if (!status)
- zl_lib->load_ref++;
-
- /* Clean up DOFF resources */
- if (opened_doff)
- dof_close(zl_lib);
-
- dev_dbg(bridge, "%s: lib: %p flags: 0x%x entry: %p, status 0x%x\n",
- __func__, lib, flags, entry, status);
-
- return status;
-}
-
-/*
- * ======== dbll_open ========
- */
-int dbll_open(struct dbll_tar_obj *target, char *file, dbll_flags flags,
- struct dbll_library_obj **lib_obj)
-{
- struct dbll_tar_obj *zl_target = (struct dbll_tar_obj *)target;
- struct dbll_library_obj *zl_lib = NULL;
- s32 err;
- int status = 0;
-
- zl_lib = zl_target->head;
- while (zl_lib != NULL) {
- if (strcmp(zl_lib->file_name, file) == 0) {
- /* Library is already opened */
- zl_lib->open_ref++;
- break;
- }
- zl_lib = zl_lib->next;
- }
- if (zl_lib == NULL) {
- /* Allocate DBL library object */
- zl_lib = kzalloc(sizeof(struct dbll_library_obj), GFP_KERNEL);
- if (zl_lib == NULL) {
- status = -ENOMEM;
- } else {
- zl_lib->pos = 0;
- /* Increment ref count to allow close on failure
- * later on */
- zl_lib->open_ref++;
- zl_lib->target_obj = zl_target;
- /* Keep a copy of the file name */
- zl_lib->file_name = kzalloc(strlen(file) + 1,
- GFP_KERNEL);
- if (zl_lib->file_name == NULL) {
- status = -ENOMEM;
- } else {
- strncpy(zl_lib->file_name, file,
- strlen(file) + 1);
- }
- zl_lib->sym_tab = NULL;
- }
- }
- /*
- * Set up objects needed by the dynamic loader
- */
- if (status)
- goto func_cont;
-
- /* Stream */
- zl_lib->stream.dl_stream.read_buffer = dbll_read_buffer;
- zl_lib->stream.dl_stream.set_file_posn = dbll_set_file_posn;
- zl_lib->stream.lib = zl_lib;
- /* Symbol */
- zl_lib->symbol.dl_symbol.add_to_symbol_table = dbll_add_to_symbol_table;
- zl_lib->symbol.dl_symbol.find_matching_symbol = dbll_find_symbol;
- zl_lib->symbol.dl_symbol.purge_symbol_table = dbll_purge_symbol_table;
- zl_lib->symbol.dl_symbol.dload_allocate = allocate;
- zl_lib->symbol.dl_symbol.dload_deallocate = deallocate;
- zl_lib->symbol.dl_symbol.error_report = dbll_err_report;
- zl_lib->symbol.lib = zl_lib;
- /* Allocate */
- zl_lib->allocate.dl_alloc.dload_allocate = dbll_rmm_alloc;
- zl_lib->allocate.dl_alloc.dload_deallocate = rmm_dealloc;
- zl_lib->allocate.lib = zl_lib;
- /* Init */
- zl_lib->init.dl_init.connect = connect;
- zl_lib->init.dl_init.readmem = read_mem;
- zl_lib->init.dl_init.writemem = write_mem;
- zl_lib->init.dl_init.fillmem = fill_mem;
- zl_lib->init.dl_init.execute = execute;
- zl_lib->init.dl_init.release = release;
- zl_lib->init.lib = zl_lib;
- if (!status && zl_lib->fp == NULL)
- status = dof_open(zl_lib);
-
- zl_lib->pos = (*(zl_lib->target_obj->attrs.ftell)) (zl_lib->fp);
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0, SEEK_SET);
- /* Create a hash table for symbols if flag is set */
- if (zl_lib->sym_tab != NULL || !(flags & DBLL_SYMB))
- goto func_cont;
-
- zl_lib->sym_tab =
- gh_create(sizeof(struct dbll_symbol), name_hash, name_match,
- sym_delete);
- if (IS_ERR(zl_lib->sym_tab)) {
- status = PTR_ERR(zl_lib->sym_tab);
- zl_lib->sym_tab = NULL;
- } else {
- /* Do a fake load to get symbols - set write func to no_op */
- zl_lib->init.dl_init.writemem = no_op;
- err = dynamic_open_module(&zl_lib->stream.dl_stream,
- &zl_lib->symbol.dl_symbol,
- &zl_lib->allocate.dl_alloc,
- &zl_lib->init.dl_init, 0,
- &zl_lib->dload_mod_obj);
- if (err != 0) {
- status = -EILSEQ;
- } else {
- /* Now that we have the symbol table, we can unload */
- err = dynamic_unload_module(zl_lib->dload_mod_obj,
- &zl_lib->symbol.dl_symbol,
- &zl_lib->allocate.dl_alloc,
- &zl_lib->init.dl_init);
- if (err != 0)
- status = -EILSEQ;
-
- zl_lib->dload_mod_obj = NULL;
- }
- }
-func_cont:
- if (!status) {
- if (zl_lib->open_ref == 1) {
- /* First time opened - insert in list */
- if (zl_target->head)
- (zl_target->head)->prev = zl_lib;
-
- zl_lib->prev = NULL;
- zl_lib->next = zl_target->head;
- zl_target->head = zl_lib;
- }
- *lib_obj = (struct dbll_library_obj *)zl_lib;
- } else {
- *lib_obj = NULL;
- if (zl_lib != NULL)
- dbll_close((struct dbll_library_obj *)zl_lib);
-
- }
-
- dev_dbg(bridge, "%s: target: %p file: %s lib_obj: %p, status 0x%x\n",
- __func__, target, file, lib_obj, status);
-
- return status;
-}
-
-/*
- * ======== dbll_read_sect ========
- * Get the content of a COFF section.
- */
-int dbll_read_sect(struct dbll_library_obj *lib, char *name,
- char *buf, u32 size)
-{
- struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
- bool opened_doff = false;
- u32 byte_size; /* size of bytes */
- u32 ul_sect_size; /* size of section */
- const struct ldr_section_info *sect = NULL;
- int status = 0;
-
- /* If DOFF file is not open, we open it. */
- if (zl_lib != NULL) {
- if (zl_lib->fp == NULL) {
- status = dof_open(zl_lib);
- if (!status)
- opened_doff = true;
-
- } else {
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp,
- zl_lib->pos,
- SEEK_SET);
- }
- } else {
- status = -EFAULT;
- }
- if (status)
- goto func_cont;
-
- byte_size = 1;
- if (!dload_get_section_info(zl_lib->desc, name, &sect)) {
- status = -ENXIO;
- goto func_cont;
- }
- /*
- * Ensure the supplied buffer size is sufficient to store
- * the section buf to be read.
- */
- ul_sect_size = sect->size * byte_size;
- /* Make sure size is even for good swap */
- if (ul_sect_size % 2)
- ul_sect_size++;
-
- /* Align size */
- ul_sect_size = DOFF_ALIGN(ul_sect_size);
- if (ul_sect_size > size) {
- status = -EPERM;
- } else {
- if (!dload_get_section(zl_lib->desc, sect, buf))
- status = -EBADF;
-
- }
-func_cont:
- if (opened_doff) {
- dof_close(zl_lib);
- opened_doff = false;
- }
-
- dev_dbg(bridge, "%s: lib: %p name: %s buf: %p size: 0x%x, status 0x%x\n",
- __func__, lib, name, buf, size, status);
- return status;
-}
-
-/*
- * ======== dbll_unload ========
- */
-void dbll_unload(struct dbll_library_obj *lib, struct dbll_attrs *attrs)
-{
- struct dbll_library_obj *zl_lib = (struct dbll_library_obj *)lib;
- s32 err = 0;
-
- dev_dbg(bridge, "%s: lib: %p\n", __func__, lib);
- zl_lib->load_ref--;
- /* Unload only if reference count is 0 */
- if (zl_lib->load_ref != 0)
- return;
-
- zl_lib->target_obj->attrs = *attrs;
- if (zl_lib->dload_mod_obj) {
- err = dynamic_unload_module(zl_lib->dload_mod_obj,
- &zl_lib->symbol.dl_symbol,
- &zl_lib->allocate.dl_alloc,
- &zl_lib->init.dl_init);
- if (err != 0)
- dev_dbg(bridge, "%s: failed: 0x%x\n", __func__, err);
- }
- /* remove symbols from symbol table */
- if (zl_lib->sym_tab != NULL) {
- gh_delete(zl_lib->sym_tab);
- zl_lib->sym_tab = NULL;
- }
- /* delete DOFF desc since it holds *lots* of host OS
- * resources */
- dof_close(zl_lib);
-}
-
-/*
- * ======== dof_close ========
- */
-static void dof_close(struct dbll_library_obj *zl_lib)
-{
- if (zl_lib->desc) {
- dload_module_close(zl_lib->desc);
- zl_lib->desc = NULL;
- }
- /* close file */
- if (zl_lib->fp) {
- (zl_lib->target_obj->attrs.fclose) (zl_lib->fp);
- zl_lib->fp = NULL;
- }
-}
-
-/*
- * ======== dof_open ========
- */
-static int dof_open(struct dbll_library_obj *zl_lib)
-{
- void *open = *(zl_lib->target_obj->attrs.fopen);
- int status = 0;
-
- /* First open the file for the dynamic loader, then open COF */
- zl_lib->fp =
- (void *)((dbll_f_open_fxn) (open)) (zl_lib->file_name, "rb");
-
- /* Open DOFF module */
- if (zl_lib->fp && zl_lib->desc == NULL) {
- (*(zl_lib->target_obj->attrs.fseek)) (zl_lib->fp, (long)0,
- SEEK_SET);
- zl_lib->desc =
- dload_module_open(&zl_lib->stream.dl_stream,
- &zl_lib->symbol.dl_symbol);
- if (zl_lib->desc == NULL) {
- (zl_lib->target_obj->attrs.fclose) (zl_lib->fp);
- zl_lib->fp = NULL;
- status = -EBADF;
- }
- } else {
- status = -EBADF;
- }
-
- return status;
-}
-
-/*
- * ======== name_hash ========
- */
-static u32 name_hash(const void *key)
-{
- u32 hash;
- const char *name = key;
-
- hash = 0;
-
- while (*name) {
- hash <<= 1;
- hash ^= *name++;
- }
-
- return hash;
-}
-
-/*
- * ======== name_match ========
- */
-static bool name_match(const void *key, const void *sp)
-{
- if ((key != NULL) && (sp != NULL)) {
- if (strcmp(key, ((struct dbll_symbol *)sp)->name) == 0)
- return true;
- }
- return false;
-}
-
-/*
- * ======== no_op ========
- */
-static int no_op(struct dynamic_loader_initialize *thisptr, void *bufr,
- ldr_addr locn, struct ldr_section_info *info, unsigned bytsize)
-{
- return 1;
-}
-
-/*
- * ======== sym_delete ========
- */
-static void sym_delete(void *value)
-{
- struct dbll_symbol *sp = (struct dbll_symbol *)value;
-
- kfree(sp->name);
-}
-
-/*
- * Dynamic Loader Functions
- */
-
-/* dynamic_loader_stream */
-/*
- * ======== dbll_read_buffer ========
- */
-static int dbll_read_buffer(struct dynamic_loader_stream *this, void *buffer,
- unsigned bufsize)
-{
- struct dbll_stream *pstream = (struct dbll_stream *)this;
- struct dbll_library_obj *lib;
- int bytes_read = 0;
-
- lib = pstream->lib;
- if (lib != NULL) {
- bytes_read =
- (*(lib->target_obj->attrs.fread)) (buffer, 1, bufsize,
- lib->fp);
- }
- return bytes_read;
-}
-
-/*
- * ======== dbll_set_file_posn ========
- */
-static int dbll_set_file_posn(struct dynamic_loader_stream *this,
- unsigned int pos)
-{
- struct dbll_stream *pstream = (struct dbll_stream *)this;
- struct dbll_library_obj *lib;
- int status = 0; /* Success */
-
- lib = pstream->lib;
- if (lib != NULL) {
- status = (*(lib->target_obj->attrs.fseek)) (lib->fp, (long)pos,
- SEEK_SET);
- }
-
- return status;
-}
-
-/* dynamic_loader_sym */
-
-/*
- * ======== dbll_find_symbol ========
- */
-static struct dynload_symbol *dbll_find_symbol(struct dynamic_loader_sym *this,
- const char *name)
-{
- struct dynload_symbol *ret_sym;
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- struct dbll_sym_val *dbll_sym = NULL;
- bool status = false; /* Symbol not found yet */
-
- lib = ldr_sym->lib;
- if (lib != NULL) {
- if (lib->target_obj->attrs.sym_lookup) {
- /* Check current lib + base lib + dep lib +
- * persistent lib */
- status = (*(lib->target_obj->attrs.sym_lookup))
- (lib->target_obj->attrs.sym_handle,
- lib->target_obj->attrs.sym_arg,
- lib->target_obj->attrs.rmm_handle, name,
- &dbll_sym);
- } else {
- /* Just check current lib for symbol */
- status = dbll_get_addr((struct dbll_library_obj *)lib,
- (char *)name, &dbll_sym);
- if (!status) {
- status = dbll_get_c_addr(
- (struct dbll_library_obj *)
- lib, (char *)name,
- &dbll_sym);
- }
- }
- }
-
- if (!status && gbl_search)
- dev_dbg(bridge, "%s: Symbol not found: %s\n", __func__, name);
-
- ret_sym = (struct dynload_symbol *)dbll_sym;
- return ret_sym;
-}
-
-/*
- * ======== find_in_symbol_table ========
- */
-static struct dynload_symbol *find_in_symbol_table(struct dynamic_loader_sym
- *this, const char *name,
- unsigned moduleid)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- struct dbll_symbol *sym;
-
- lib = ldr_sym->lib;
- sym = (struct dbll_symbol *)gh_find(lib->sym_tab, (char *)name);
-
- if (IS_ERR(sym))
- return NULL;
-
- return (struct dynload_symbol *)&sym->value;
-}
-
-/*
- * ======== dbll_add_to_symbol_table ========
- */
-static struct dynload_symbol *dbll_add_to_symbol_table(struct dynamic_loader_sym
- *this, const char *name,
- unsigned module_id)
-{
- struct dbll_symbol *sym_ptr = NULL;
- struct dbll_symbol symbol;
- struct dynload_symbol *dbll_sym = NULL;
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- struct dynload_symbol *ret;
-
- lib = ldr_sym->lib;
-
- /* Check to see if symbol is already defined in symbol table */
- if (!(lib->target_obj->attrs.base_image)) {
- gbl_search = false;
- dbll_sym = dbll_find_symbol(this, name);
- gbl_search = true;
- if (dbll_sym) {
- redefined_symbol = true;
- dev_dbg(bridge, "%s already defined in symbol table\n",
- name);
- return NULL;
- }
- }
- /* Allocate string to copy symbol name */
- symbol.name = kzalloc(strlen((char *const)name) + 1, GFP_KERNEL);
- if (symbol.name == NULL)
- return NULL;
-
- if (symbol.name != NULL) {
- /* Just copy name (value will be filled in by dynamic loader) */
- strncpy(symbol.name, (char *const)name,
- strlen((char *const)name) + 1);
-
- /* Add symbol to symbol table */
- sym_ptr =
- (struct dbll_symbol *)gh_insert(lib->sym_tab, (void *)name,
- (void *)&symbol);
- if (IS_ERR(sym_ptr)) {
- kfree(symbol.name);
- sym_ptr = NULL;
- }
-
- }
- if (sym_ptr != NULL)
- ret = (struct dynload_symbol *)&sym_ptr->value;
- else
- ret = NULL;
-
- return ret;
-}
-
-/*
- * ======== dbll_purge_symbol_table ========
- */
-static void dbll_purge_symbol_table(struct dynamic_loader_sym *this,
- unsigned module_id)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
-
- lib = ldr_sym->lib;
- /* May not need to do anything */
-}
-
-/*
- * ======== allocate ========
- */
-static void *allocate(struct dynamic_loader_sym *this, unsigned memsize)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- void *buf;
-
- lib = ldr_sym->lib;
-
- buf = kzalloc(memsize, GFP_KERNEL);
-
- return buf;
-}
-
-/*
- * ======== deallocate ========
- */
-static void deallocate(struct dynamic_loader_sym *this, void *mem_ptr)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
-
- lib = ldr_sym->lib;
-
- kfree(mem_ptr);
-}
-
-/*
- * ======== dbll_err_report ========
- */
-static void dbll_err_report(struct dynamic_loader_sym *this, const char *errstr,
- va_list args)
-{
- struct ldr_symbol *ldr_sym = (struct ldr_symbol *)this;
- struct dbll_library_obj *lib;
- char temp_buf[MAXEXPR];
-
- lib = ldr_sym->lib;
- vsnprintf((char *)temp_buf, MAXEXPR, (char *)errstr, args);
- dev_dbg(bridge, "%s\n", temp_buf);
-}
-
-/* dynamic_loader_allocate */
-
-/*
- * ======== dbll_rmm_alloc ========
- */
-static int dbll_rmm_alloc(struct dynamic_loader_allocate *this,
- struct ldr_section_info *info, unsigned align)
-{
- struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this;
- struct dbll_library_obj *lib;
- int status = 0;
- u32 mem_sect_type;
- struct rmm_addr rmm_addr_obj;
- s32 ret = true;
- unsigned stype = DLOAD_SECTION_TYPE(info->type);
- char *token = NULL;
- char *sz_sec_last_token = NULL;
- char *sz_last_token = NULL;
- char *sz_sect_name = NULL;
- char *psz_cur;
- s32 token_len = 0;
- s32 seg_id = -1;
- s32 req = -1;
- s32 count = 0;
- u32 alloc_size = 0;
- u32 run_addr_flag = 0;
-
- lib = dbll_alloc_obj->lib;
-
- mem_sect_type =
- (stype == DLOAD_TEXT) ? DBLL_CODE : (stype ==
- DLOAD_BSS) ? DBLL_BSS :
- DBLL_DATA;
-
- /* Attempt to extract the segment ID and requirement information from
- the name of the section */
- token_len = strlen((char *)(info->name)) + 1;
-
- sz_sect_name = kzalloc(token_len, GFP_KERNEL);
- sz_last_token = kzalloc(token_len, GFP_KERNEL);
- sz_sec_last_token = kzalloc(token_len, GFP_KERNEL);
-
- if (sz_sect_name == NULL || sz_sec_last_token == NULL ||
- sz_last_token == NULL) {
- status = -ENOMEM;
- goto func_cont;
- }
- strncpy(sz_sect_name, (char *)(info->name), token_len);
- psz_cur = sz_sect_name;
- while ((token = strsep(&psz_cur, ":")) && *token != '\0') {
- strncpy(sz_sec_last_token, sz_last_token,
- strlen(sz_last_token) + 1);
- strncpy(sz_last_token, token, strlen(token) + 1);
- token = strsep(&psz_cur, ":");
- count++; /* optimizes processing */
- }
- /* If token is 0 or 1, and sz_sec_last_token is DYN_DARAM or DYN_SARAM,
- or DYN_EXTERNAL, then mem granularity information is present
- within the section name - only process if there are at least three
- tokens within the section name (just a minor optimization) */
- if (count >= 3) {
- status = kstrtos32(sz_last_token, 10, &req);
- if (status)
- goto func_cont;
- }
-
- if ((req == 0) || (req == 1)) {
- if (strcmp(sz_sec_last_token, "DYN_DARAM") == 0) {
- seg_id = 0;
- } else {
- if (strcmp(sz_sec_last_token, "DYN_SARAM") == 0) {
- seg_id = 1;
- } else {
- if (strcmp(sz_sec_last_token,
- "DYN_EXTERNAL") == 0)
- seg_id = 2;
- }
- }
- }
-func_cont:
- kfree(sz_sect_name);
- sz_sect_name = NULL;
- kfree(sz_last_token);
- sz_last_token = NULL;
- kfree(sz_sec_last_token);
- sz_sec_last_token = NULL;
-
- if (mem_sect_type == DBLL_CODE)
- alloc_size = info->size + GEM_L1P_PREFETCH_SIZE;
- else
- alloc_size = info->size;
-
- if (info->load_addr != info->run_addr)
- run_addr_flag = 1;
- /* TODO - ideally, we can pass the alignment requirement also
- * from here */
- if (lib != NULL) {
- status =
- (lib->target_obj->attrs.alloc) (lib->target_obj->attrs.
- rmm_handle, mem_sect_type,
- alloc_size, align,
- (u32 *) &rmm_addr_obj,
- seg_id, req, false);
- }
- if (status) {
- ret = false;
- } else {
- /* RMM gives word address. Need to convert to byte address */
- info->load_addr = rmm_addr_obj.addr * DSPWORDSIZE;
- if (!run_addr_flag)
- info->run_addr = info->load_addr;
- info->context = (u32) rmm_addr_obj.segid;
- dev_dbg(bridge, "%s: %s base = 0x%x len = 0x%x, info->run_addr 0x%x, info->load_addr 0x%x\n",
- __func__, info->name, info->load_addr / DSPWORDSIZE,
- info->size / DSPWORDSIZE, info->run_addr,
- info->load_addr);
- }
- return ret;
-}
-
-/*
- * ======== rmm_dealloc ========
- */
-static void rmm_dealloc(struct dynamic_loader_allocate *this,
- struct ldr_section_info *info)
-{
- struct dbll_alloc *dbll_alloc_obj = (struct dbll_alloc *)this;
- struct dbll_library_obj *lib;
- u32 segid;
- int status = 0;
- unsigned stype = DLOAD_SECTION_TYPE(info->type);
- u32 mem_sect_type;
- u32 free_size = 0;
-
- mem_sect_type =
- (stype == DLOAD_TEXT) ? DBLL_CODE : (stype ==
- DLOAD_BSS) ? DBLL_BSS :
- DBLL_DATA;
- lib = dbll_alloc_obj->lib;
- /* segid was set by alloc function */
- segid = (u32) info->context;
- if (mem_sect_type == DBLL_CODE)
- free_size = info->size + GEM_L1P_PREFETCH_SIZE;
- else
- free_size = info->size;
- if (lib != NULL) {
- status =
- (lib->target_obj->attrs.free) (lib->target_obj->attrs.
- sym_handle, segid,
- info->load_addr /
- DSPWORDSIZE, free_size,
- false);
- }
-}
-
-/* dynamic_loader_initialize */
-/*
- * ======== connect ========
- */
-static int connect(struct dynamic_loader_initialize *this)
-{
- return true;
-}
-
-/*
- * ======== read_mem ========
- * This function does not need to be implemented.
- */
-static int read_mem(struct dynamic_loader_initialize *this, void *buf,
- ldr_addr addr, struct ldr_section_info *info,
- unsigned nbytes)
-{
- struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
- struct dbll_library_obj *lib;
- int bytes_read = 0;
-
- lib = init_obj->lib;
- /* Need bridge_brd_read function */
- return bytes_read;
-}
-
-/*
- * ======== write_mem ========
- */
-static int write_mem(struct dynamic_loader_initialize *this, void *buf,
- ldr_addr addr, struct ldr_section_info *info,
- unsigned bytes)
-{
- struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
- struct dbll_library_obj *lib;
- struct dbll_tar_obj *target_obj;
- struct dbll_sect_info sect_info;
- u32 mem_sect_type;
- bool ret = true;
-
- lib = init_obj->lib;
- if (!lib)
- return false;
-
- target_obj = lib->target_obj;
-
- mem_sect_type =
- (DLOAD_SECTION_TYPE(info->type) ==
- DLOAD_TEXT) ? DBLL_CODE : DBLL_DATA;
- if (target_obj && target_obj->attrs.write) {
- ret =
- (*target_obj->attrs.write) (target_obj->attrs.input_params,
- addr, buf, bytes,
- mem_sect_type);
-
- if (target_obj->attrs.log_write) {
- sect_info.name = info->name;
- sect_info.sect_run_addr = info->run_addr;
- sect_info.sect_load_addr = info->load_addr;
- sect_info.size = info->size;
- sect_info.type = mem_sect_type;
- /* Pass the information about what we've written to
- * another module */
- (*target_obj->attrs.log_write) (target_obj->attrs.
- log_write_handle,
- &sect_info, addr,
- bytes);
- }
- }
- return ret;
-}
-
-/*
- * ======== fill_mem ========
- * Fill bytes of memory at a given address with a given value by
- * writing from a buffer containing the given value. Write in
- * sets of MAXEXPR (128) bytes to avoid large stack buffer issues.
- */
-static int fill_mem(struct dynamic_loader_initialize *this, ldr_addr addr,
- struct ldr_section_info *info, unsigned bytes, unsigned val)
-{
- bool ret = true;
- char *pbuf;
- struct dbll_library_obj *lib;
- struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
-
- lib = init_obj->lib;
- pbuf = NULL;
- /* Pass the NULL pointer to write_mem to get the start address of Shared
- memory. This is a trick to just get the start address, there is no
- writing taking place with this Writemem
- */
- if ((lib->target_obj->attrs.write) != (dbll_write_fxn) no_op)
- write_mem(this, &pbuf, addr, info, 0);
- if (pbuf)
- memset(pbuf, val, bytes);
-
- return ret;
-}
-
-/*
- * ======== execute ========
- */
-static int execute(struct dynamic_loader_initialize *this, ldr_addr start)
-{
- struct dbll_init_obj *init_obj = (struct dbll_init_obj *)this;
- struct dbll_library_obj *lib;
- bool ret = true;
-
- lib = init_obj->lib;
- /* Save entry point */
- if (lib != NULL)
- lib->entry = (u32) start;
-
- return ret;
-}
-
-/*
- * ======== release ========
- */
-static void release(struct dynamic_loader_initialize *this)
-{
-}
-
-#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
-/**
- * find_symbol_context - Basic symbol context structure
- * @address: Symbol Address
- * @offset_range: Offset range where the search for the DSP symbol
- * started.
- * @cur_best_offset: Best offset to start looking for the DSP symbol
- * @sym_addr: Address of the DSP symbol
- * @name: Symbol name
- *
- */
-struct find_symbol_context {
- /* input */
- u32 address;
- u32 offset_range;
- /* state */
- u32 cur_best_offset;
- /* output */
- u32 sym_addr;
- char name[120];
-};
-
-/**
- * find_symbol_callback() - Validates symbol address and copies the symbol name
- * to the user data.
- * @elem: dsp library context
- * @user_data: Find symbol context
- *
- */
-void find_symbol_callback(void *elem, void *user_data)
-{
- struct dbll_symbol *symbol = elem;
- struct find_symbol_context *context = user_data;
- u32 symbol_addr = symbol->value.value;
- u32 offset = context->address - symbol_addr;
-
- /*
- * Address given should be greater than symbol address,
- * symbol address should be within specified range
- * and the offset should be better than previous one
- */
- if (context->address >= symbol_addr && symbol_addr < (u32)-1 &&
- offset < context->cur_best_offset) {
- context->cur_best_offset = offset;
- context->sym_addr = symbol_addr;
- strlcpy(context->name, symbol->name, sizeof(context->name));
- }
-
- return;
-}
-
-/**
- * dbll_find_dsp_symbol() - This function retrieves the dsp symbol from the dsp binary.
- * @zl_lib: DSP binary obj library pointer
- * @address: Given address to find the dsp symbol
- * @offset_range: offset range to look for dsp symbol
- * @sym_addr_output: Symbol Output address
- * @name_output: String with the dsp symbol
- *
- * This function retrieves the dsp symbol from the dsp binary.
- */
-bool dbll_find_dsp_symbol(struct dbll_library_obj *zl_lib, u32 address,
- u32 offset_range, u32 *sym_addr_output,
- char *name_output)
-{
- bool status = false;
- struct find_symbol_context context;
-
- context.address = address;
- context.offset_range = offset_range;
- context.cur_best_offset = offset_range;
- context.sym_addr = 0;
- context.name[0] = '\0';
-
- gh_iterate(zl_lib->sym_tab, find_symbol_callback, &context);
-
- if (context.name[0]) {
- status = true;
- strcpy(name_output, context.name);
- *sym_addr_output = context.sym_addr;
- }
-
- return status;
-}
-#endif