diff options
author | Dmitry Torokhov | 2014-10-03 20:24:46 +0200 |
---|---|---|
committer | Dmitry Torokhov | 2014-10-03 20:24:46 +0200 |
commit | 447a8b858e4bda41c394b1bc7fdbc9dc0bdf44f6 (patch) | |
tree | 676e741f2552c9cb301e1e49c557b92bf8940f55 /drivers/staging/tidspbridge/dynload | |
parent | Input: i8042 - fix Asus X450LCP touchpad detection (diff) | |
parent | Input: soc_button_array - convert to platform bus (diff) | |
download | kernel-qcow2-linux-447a8b858e4bda41c394b1bc7fdbc9dc0bdf44f6.tar.gz kernel-qcow2-linux-447a8b858e4bda41c394b1bc7fdbc9dc0bdf44f6.tar.xz kernel-qcow2-linux-447a8b858e4bda41c394b1bc7fdbc9dc0bdf44f6.zip |
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.18.
Diffstat (limited to 'drivers/staging/tidspbridge/dynload')
-rw-r--r-- | drivers/staging/tidspbridge/dynload/cload.c | 1952 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/dload_internal.h | 344 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/doff.h | 354 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/getsection.c | 407 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/header.h | 49 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/module_list.h | 159 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/params.h | 226 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/reloc.c | 484 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/reloc_table.h | 102 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/reloc_table_c6000.c | 257 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/tramp.c | 1143 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/dynload/tramp_table_c6000.c | 164 |
12 files changed, 0 insertions, 5641 deletions
diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c deleted file mode 100644 index 9d54744805b8..000000000000 --- a/drivers/staging/tidspbridge/dynload/cload.c +++ /dev/null @@ -1,1952 +0,0 @@ -/* - * cload.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/slab.h> - -#include "header.h" - -#include "module_list.h" -#define LINKER_MODULES_HEADER ("_" MODULES_HEADER) - -/* - * forward references - */ -static void dload_symbols(struct dload_state *dlthis); -static void dload_data(struct dload_state *dlthis); -static void allocate_sections(struct dload_state *dlthis); -static void string_table_free(struct dload_state *dlthis); -static void symbol_table_free(struct dload_state *dlthis); -static void section_table_free(struct dload_state *dlthis); -static void init_module_handle(struct dload_state *dlthis); -#if BITS_PER_AU > BITS_PER_BYTE -static char *unpack_name(struct dload_state *dlthis, u32 soffset); -#endif - -static const char cinitname[] = { ".cinit" }; -static const char loader_dllview_root[] = { "?DLModules?" }; - -/* - * Error strings - */ -static const char readstrm[] = { "Error reading %s from input stream" }; -static const char err_alloc[] = { "Syms->dload_allocate( %d ) failed" }; -static const char tgtalloc[] = { - "Target memory allocate failed, section %s size " FMT_UI32 }; -static const char initfail[] = { "%s to target address " FMT_UI32 " failed" }; -static const char dlvwrite[] = { "Write to DLLview list failed" }; -static const char iconnect[] = { "Connect call to init interface failed" }; -static const char err_checksum[] = { "Checksum failed on %s" }; - -/************************************************************************* - * Procedure dload_error - * - * Parameters: - * errtxt description of the error, printf style - * ... additional information - * - * Effect: - * Reports or records the error as appropriate. - *********************************************************************** */ -void dload_error(struct dload_state *dlthis, const char *errtxt, ...) -{ - va_list args; - - va_start(args, errtxt); - dlthis->mysym->error_report(dlthis->mysym, errtxt, args); - va_end(args); - dlthis->dload_errcount += 1; - -} /* dload_error */ - -#define DL_ERROR(zza, zzb) dload_error(dlthis, zza, zzb) - -/************************************************************************* - * Procedure dload_syms_error - * - * Parameters: - * errtxt description of the error, printf style - * ... additional information - * - * Effect: - * Reports or records the error as appropriate. - *********************************************************************** */ -void dload_syms_error(struct dynamic_loader_sym *syms, const char *errtxt, ...) -{ - va_list args; - - va_start(args, errtxt); - syms->error_report(syms, errtxt, args); - va_end(args); -} - -/************************************************************************* - * Procedure dynamic_load_module - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * init Target-side memory initialization - * options Option flags DLOAD_* - * mhandle A module handle for use with Dynamic_Unload - * - * Effect: - * The module image is read using *module. Target storage for the new - * image is - * obtained from *alloc. Symbols defined and referenced by the module are - * managed using *syms. The image is then relocated and references - * resolved as necessary, and the resulting executable bits are placed - * into target memory using *init. - * - * Returns: - * On a successful load, a module handle is placed in *mhandle, - * and zero is returned. On error, the number of errors detected is - * returned. Individual errors are reported during the load process - * using syms->error_report(). - ********************************************************************** */ -int dynamic_load_module(struct dynamic_loader_stream *module, - struct dynamic_loader_sym *syms, - struct dynamic_loader_allocate *alloc, - struct dynamic_loader_initialize *init, - unsigned options, void **mhandle) -{ - register unsigned *dp, sz; - struct dload_state dl_state; /* internal state for this call */ - - /* blast our internal state */ - dp = (unsigned *)&dl_state; - for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1) - *dp++ = 0; - - /* Enable _only_ BSS initialization if enabled by user */ - if ((options & DLOAD_INITBSS) == DLOAD_INITBSS) - dl_state.myoptions = DLOAD_INITBSS; - - /* Check that mandatory arguments are present */ - if (!module || !syms) { - dload_error(&dl_state, "Required parameter is NULL"); - } else { - dl_state.strm = module; - dl_state.mysym = syms; - dload_headers(&dl_state); - if (!dl_state.dload_errcount) - dload_strings(&dl_state, false); - if (!dl_state.dload_errcount) - dload_sections(&dl_state); - - if (init && !dl_state.dload_errcount) { - if (init->connect(init)) { - dl_state.myio = init; - dl_state.myalloc = alloc; - /* do now, before reducing symbols */ - allocate_sections(&dl_state); - } else - dload_error(&dl_state, iconnect); - } - - if (!dl_state.dload_errcount) { - /* fix up entry point address */ - unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1; - if (sref < dl_state.allocated_secn_count) - dl_state.dfile_hdr.df_entrypt += - dl_state.ldr_sections[sref].run_addr; - - dload_symbols(&dl_state); - } - - if (init && !dl_state.dload_errcount) - dload_data(&dl_state); - - init_module_handle(&dl_state); - - /* dl_state.myio is init or 0 at this point. */ - if (dl_state.myio) { - if ((!dl_state.dload_errcount) && - (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF) && - (!init->execute(init, - dl_state.dfile_hdr.df_entrypt))) - dload_error(&dl_state, "Init->Execute Failed"); - init->release(init); - } - - symbol_table_free(&dl_state); - section_table_free(&dl_state); - string_table_free(&dl_state); - dload_tramp_cleanup(&dl_state); - - if (dl_state.dload_errcount) { - dynamic_unload_module(dl_state.myhandle, syms, alloc, - init); - dl_state.myhandle = NULL; - } - } - - if (mhandle) - *mhandle = dl_state.myhandle; /* give back the handle */ - - return dl_state.dload_errcount; -} /* DLOAD_File */ - -/************************************************************************* - * Procedure dynamic_open_module - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * init Target-side memory initialization - * options Option flags DLOAD_* - * mhandle A module handle for use with Dynamic_Unload - * - * Effect: - * The module image is read using *module. Target storage for the new - * image is - * obtained from *alloc. Symbols defined and referenced by the module are - * managed using *syms. The image is then relocated and references - * resolved as necessary, and the resulting executable bits are placed - * into target memory using *init. - * - * Returns: - * On a successful load, a module handle is placed in *mhandle, - * and zero is returned. On error, the number of errors detected is - * returned. Individual errors are reported during the load process - * using syms->error_report(). - ********************************************************************** */ -int -dynamic_open_module(struct dynamic_loader_stream *module, - struct dynamic_loader_sym *syms, - struct dynamic_loader_allocate *alloc, - struct dynamic_loader_initialize *init, - unsigned options, void **mhandle) -{ - register unsigned *dp, sz; - struct dload_state dl_state; /* internal state for this call */ - - /* blast our internal state */ - dp = (unsigned *)&dl_state; - for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1) - *dp++ = 0; - - /* Enable _only_ BSS initialization if enabled by user */ - if ((options & DLOAD_INITBSS) == DLOAD_INITBSS) - dl_state.myoptions = DLOAD_INITBSS; - - /* Check that mandatory arguments are present */ - if (!module || !syms) { - dload_error(&dl_state, "Required parameter is NULL"); - } else { - dl_state.strm = module; - dl_state.mysym = syms; - dload_headers(&dl_state); - if (!dl_state.dload_errcount) - dload_strings(&dl_state, false); - if (!dl_state.dload_errcount) - dload_sections(&dl_state); - - if (init && !dl_state.dload_errcount) { - if (init->connect(init)) { - dl_state.myio = init; - dl_state.myalloc = alloc; - /* do now, before reducing symbols */ - allocate_sections(&dl_state); - } else - dload_error(&dl_state, iconnect); - } - - if (!dl_state.dload_errcount) { - /* fix up entry point address */ - unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1; - if (sref < dl_state.allocated_secn_count) - dl_state.dfile_hdr.df_entrypt += - dl_state.ldr_sections[sref].run_addr; - - dload_symbols(&dl_state); - } - - init_module_handle(&dl_state); - - /* dl_state.myio is either 0 or init at this point. */ - if (dl_state.myio) { - if ((!dl_state.dload_errcount) && - (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF) && - (!init->execute(init, - dl_state.dfile_hdr.df_entrypt))) - dload_error(&dl_state, "Init->Execute Failed"); - init->release(init); - } - - symbol_table_free(&dl_state); - section_table_free(&dl_state); - string_table_free(&dl_state); - - if (dl_state.dload_errcount) { - dynamic_unload_module(dl_state.myhandle, syms, alloc, - init); - dl_state.myhandle = NULL; - } - } - - if (mhandle) - *mhandle = dl_state.myhandle; /* give back the handle */ - - return dl_state.dload_errcount; -} /* DLOAD_File */ - -/************************************************************************* - * Procedure dload_headers - * - * Parameters: - * none - * - * Effect: - * Loads the DOFF header and verify record. Deals with any byte-order - * issues and checks them for validity. - *********************************************************************** */ -#define COMBINED_HEADER_SIZE (sizeof(struct doff_filehdr_t)+ \ - sizeof(struct doff_verify_rec_t)) - -void dload_headers(struct dload_state *dlthis) -{ - u32 map; - - /* Read the header and the verify record as one. If we don't get it - all, we're done */ - if (dlthis->strm->read_buffer(dlthis->strm, &dlthis->dfile_hdr, - COMBINED_HEADER_SIZE) != - COMBINED_HEADER_SIZE) { - DL_ERROR(readstrm, "File Headers"); - return; - } - /* - * Verify that we have the byte order of the file correct. - * If not, must fix it before we can continue - */ - map = REORDER_MAP(dlthis->dfile_hdr.df_byte_reshuffle); - if (map != REORDER_MAP(BYTE_RESHUFFLE_VALUE)) { - /* input is either byte-shuffled or bad */ - if ((map & 0xFCFCFCFC) == 0) { /* no obviously bogus bits */ - dload_reorder(&dlthis->dfile_hdr, COMBINED_HEADER_SIZE, - map); - } - if (dlthis->dfile_hdr.df_byte_reshuffle != - BYTE_RESHUFFLE_VALUE) { - /* didn't fix the problem, the byte swap map is bad */ - dload_error(dlthis, - "Bad byte swap map " FMT_UI32 " in header", - dlthis->dfile_hdr.df_byte_reshuffle); - return; - } - dlthis->reorder_map = map; /* keep map for future use */ - } - - /* - * Verify checksum of header and verify record - */ - if (~dload_checksum(&dlthis->dfile_hdr, - sizeof(struct doff_filehdr_t)) || - ~dload_checksum(&dlthis->verify, - sizeof(struct doff_verify_rec_t))) { - DL_ERROR(err_checksum, "header or verify record"); - return; - } -#if HOST_ENDIANNESS - dlthis->dfile_hdr.df_byte_reshuffle = map; /* put back for later */ -#endif - - /* Check for valid target ID */ - if ((dlthis->dfile_hdr.df_target_id != TARGET_ID) && - -(dlthis->dfile_hdr.df_target_id != TMS470_ID)) { - dload_error(dlthis, "Bad target ID 0x%x and TARGET_ID 0x%x", - dlthis->dfile_hdr.df_target_id, TARGET_ID); - return; - } - /* Check for valid file format */ - if ((dlthis->dfile_hdr.df_doff_version != DOFF0)) { - dload_error(dlthis, "Bad DOFF version 0x%x", - dlthis->dfile_hdr.df_doff_version); - return; - } - - /* - * Apply reasonableness checks to count fields - */ - if (dlthis->dfile_hdr.df_strtab_size > MAX_REASONABLE_STRINGTAB) { - dload_error(dlthis, "Excessive string table size " FMT_UI32, - dlthis->dfile_hdr.df_strtab_size); - return; - } - if (dlthis->dfile_hdr.df_no_scns > MAX_REASONABLE_SECTIONS) { - dload_error(dlthis, "Excessive section count 0x%x", - dlthis->dfile_hdr.df_no_scns); - return; - } -#ifndef TARGET_ENDIANNESS - /* - * Check that endianness does not disagree with explicit specification - */ - if ((dlthis->dfile_hdr.df_flags >> ALIGN_COFF_ENDIANNESS) & - dlthis->myoptions & ENDIANNESS_MASK) { - dload_error(dlthis, - "Input endianness disagrees with specified option"); - return; - } - dlthis->big_e_target = dlthis->dfile_hdr.df_flags & DF_BIG; -#endif - -} /* dload_headers */ - -/* COFF Section Processing - * - * COFF sections are read in and retained intact. Each record is embedded - * in a new structure that records the updated load and - * run addresses of the section */ - -static const char secn_errid[] = { "section" }; - -/************************************************************************* - * Procedure dload_sections - * - * Parameters: - * none - * - * Effect: - * Loads the section records into an internal table. - *********************************************************************** */ -void dload_sections(struct dload_state *dlthis) -{ - s16 siz; - struct doff_scnhdr_t *shp; - unsigned nsecs = dlthis->dfile_hdr.df_no_scns; - - /* allocate space for the DOFF section records */ - siz = nsecs * sizeof(struct doff_scnhdr_t); - shp = - (struct doff_scnhdr_t *)dlthis->mysym->dload_allocate(dlthis->mysym, - siz); - if (!shp) { /* not enough storage */ - DL_ERROR(err_alloc, siz); - return; - } - dlthis->sect_hdrs = shp; - - /* read in the section records */ - if (dlthis->strm->read_buffer(dlthis->strm, shp, siz) != siz) { - DL_ERROR(readstrm, secn_errid); - return; - } - - /* if we need to fix up byte order, do it now */ - if (dlthis->reorder_map) - dload_reorder(shp, siz, dlthis->reorder_map); - - /* check for validity */ - if (~dload_checksum(dlthis->sect_hdrs, siz) != - dlthis->verify.dv_scn_rec_checksum) { - DL_ERROR(err_checksum, secn_errid); - return; - } - -} /* dload_sections */ - -/***************************************************************************** - * Procedure allocate_sections - * - * Parameters: - * alloc target memory allocator class - * - * Effect: - * Assigns new (target) addresses for sections - **************************************************************************** */ -static void allocate_sections(struct dload_state *dlthis) -{ - u16 curr_sect, nsecs, siz; - struct doff_scnhdr_t *shp; - struct ldr_section_info *asecs; - struct my_handle *hndl; - nsecs = dlthis->dfile_hdr.df_no_scns; - if (!nsecs) - return; - if ((dlthis->myalloc == NULL) && - (dlthis->dfile_hdr.df_target_scns > 0)) { - DL_ERROR("Arg 3 (alloc) required but NULL", 0); - return; - } - /* - * allocate space for the module handle, which we will keep for unload - * purposes include an additional section store for an auto-generated - * trampoline section in case we need it. - */ - siz = (dlthis->dfile_hdr.df_target_scns + 1) * - sizeof(struct ldr_section_info) + MY_HANDLE_SIZE; - - hndl = - (struct my_handle *)dlthis->mysym->dload_allocate(dlthis->mysym, - siz); - if (!hndl) { /* not enough storage */ - DL_ERROR(err_alloc, siz); - return; - } - /* initialize the handle header */ - hndl->dm.next = hndl->dm.prev = hndl; /* circular list */ - hndl->dm.root = NULL; - hndl->dm.dbthis = 0; - dlthis->myhandle = hndl; /* save away for return */ - /* pointer to the section list of allocated sections */ - dlthis->ldr_sections = asecs = hndl->secns; - /* * Insert names into all sections, make copies of - the sections we allocate */ - shp = dlthis->sect_hdrs; - for (curr_sect = 0; curr_sect < nsecs; curr_sect++) { - u32 soffset = shp->ds_offset; -#if BITS_PER_AU <= BITS_PER_BYTE - /* attempt to insert the name of this section */ - if (soffset < dlthis->dfile_hdr.df_strtab_size) - ((struct ldr_section_info *)shp)->name = - dlthis->str_head + soffset; - else { - dload_error(dlthis, "Bad name offset in section %d", - curr_sect); - ((struct ldr_section_info *)shp)->name = NULL; - } -#endif - /* allocate target storage for sections that require it */ - if (ds_needs_allocation(shp)) { - *asecs = *(struct ldr_section_info *)shp; - asecs->context = 0; /* zero the context field */ -#if BITS_PER_AU > BITS_PER_BYTE - asecs->name = unpack_name(dlthis, soffset); - dlthis->debug_string_size = soffset + dlthis->temp_len; -#else - dlthis->debug_string_size = soffset; -#endif - if (dlthis->myalloc != NULL) { - if (!dlthis->myalloc-> - dload_allocate(dlthis->myalloc, asecs, - ds_alignment(asecs->type))) { - dload_error(dlthis, tgtalloc, - asecs->name, asecs->size); - return; - } - } - /* keep address deltas in original section table */ - shp->ds_vaddr = asecs->load_addr - shp->ds_vaddr; - shp->ds_paddr = asecs->run_addr - shp->ds_paddr; - dlthis->allocated_secn_count += 1; - } /* allocate target storage */ - shp += 1; - asecs += 1; - } -#if BITS_PER_AU <= BITS_PER_BYTE - dlthis->debug_string_size += - strlen(dlthis->str_head + dlthis->debug_string_size) + 1; -#endif -} /* allocate sections */ - -/************************************************************************* - * Procedure section_table_free - * - * Parameters: - * none - * - * Effect: - * Frees any state used by the symbol table. - * - * WARNING: - * This routine is not allowed to declare errors! - *********************************************************************** */ -static void section_table_free(struct dload_state *dlthis) -{ - struct doff_scnhdr_t *shp; - - shp = dlthis->sect_hdrs; - if (shp) - dlthis->mysym->dload_deallocate(dlthis->mysym, shp); - -} /* section_table_free */ - -/************************************************************************* - * Procedure dload_strings - * - * Parameters: - * sec_names_only If true only read in the "section names" - * portion of the string table - * - * Effect: - * Loads the DOFF string table into memory. DOFF keeps all strings in a - * big unsorted array. We just read that array into memory in bulk. - *********************************************************************** */ -static const char stringtbl[] = { "string table" }; - -void dload_strings(struct dload_state *dlthis, bool sec_names_only) -{ - u32 ssiz; - char *strbuf; - - if (sec_names_only) { - ssiz = BYTE_TO_HOST(DOFF_ALIGN - (dlthis->dfile_hdr.df_scn_name_size)); - } else { - ssiz = BYTE_TO_HOST(DOFF_ALIGN - (dlthis->dfile_hdr.df_strtab_size)); - } - if (ssiz == 0) - return; - - /* get some memory for the string table */ -#if BITS_PER_AU > BITS_PER_BYTE - strbuf = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, ssiz + - dlthis->dfile_hdr. - df_max_str_len); -#else - strbuf = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, ssiz); -#endif - if (strbuf == NULL) { - DL_ERROR(err_alloc, ssiz); - return; - } - dlthis->str_head = strbuf; -#if BITS_PER_AU > BITS_PER_BYTE - dlthis->str_temp = strbuf + ssiz; -#endif - /* read in the strings and verify them */ - if ((unsigned)(dlthis->strm->read_buffer(dlthis->strm, strbuf, - ssiz)) != ssiz) { - DL_ERROR(readstrm, stringtbl); - } - /* if we need to fix up byte order, do it now */ -#ifndef _BIG_ENDIAN - if (dlthis->reorder_map) - dload_reorder(strbuf, ssiz, dlthis->reorder_map); - - if ((!sec_names_only) && (~dload_checksum(strbuf, ssiz) != - dlthis->verify.dv_str_tab_checksum)) { - DL_ERROR(err_checksum, stringtbl); - } -#else - if (dlthis->dfile_hdr.df_byte_reshuffle != - HOST_BYTE_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) { - /* put strings in big-endian order, not in PC order */ - dload_reorder(strbuf, ssiz, - HOST_BYTE_ORDER(dlthis-> - dfile_hdr.df_byte_reshuffle)); - } - if ((!sec_names_only) && (~dload_reverse_checksum(strbuf, ssiz) != - dlthis->verify.dv_str_tab_checksum)) { - DL_ERROR(err_checksum, stringtbl); - } -#endif -} /* dload_strings */ - -/************************************************************************* - * Procedure string_table_free - * - * Parameters: - * none - * - * Effect: - * Frees any state used by the string table. - * - * WARNING: - * This routine is not allowed to declare errors! - ************************************************************************ */ -static void string_table_free(struct dload_state *dlthis) -{ - if (dlthis->str_head) - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->str_head); - -} /* string_table_free */ - -/* - * Symbol Table Maintenance Functions - * - * COFF symbols are read by dload_symbols(), which is called after - * sections have been allocated. Symbols which might be used in - * relocation (ie, not debug info) are retained in an internal temporary - * compressed table (type local_symbol). A particular symbol is recovered - * by index by calling dload_find_symbol(). dload_find_symbol - * reconstructs a more explicit representation (type SLOTVEC) which is - * used by reloc.c - */ -/* real size of debug header */ -#define DBG_HDR_SIZE (sizeof(struct dll_module) - sizeof(struct dll_sect)) - -static const char sym_errid[] = { "symbol" }; - -/************************************************************************** - * Procedure dload_symbols - * - * Parameters: - * none - * - * Effect: - * Reads in symbols and retains ones that might be needed for relocation - * purposes. - *********************************************************************** */ -/* size of symbol buffer no bigger than target data buffer, to limit stack - * usage */ -#define MY_SYM_BUF_SIZ (BYTE_TO_HOST(IMAGE_PACKET_SIZE)/\ - sizeof(struct doff_syment_t)) - -static void dload_symbols(struct dload_state *dlthis) -{ - u32 sym_count, siz, dsiz, symbols_left; - u32 checks; - struct local_symbol *sp; - struct dynload_symbol *symp; - struct dynload_symbol *newsym; - struct doff_syment_t *my_sym_buf; - - sym_count = dlthis->dfile_hdr.df_no_syms; - if (sym_count == 0) - return; - - /* - * We keep a local symbol table for all of the symbols in the input. - * This table contains only section & value info, as we do not have - * to do any name processing for locals. We reuse this storage - * as a temporary for .dllview record construction. - * Allocate storage for the whole table. Add 1 to the section count - * in case a trampoline section is auto-generated as well as the - * size of the trampoline section name so DLLView doesn't get lost. - */ - - siz = sym_count * sizeof(struct local_symbol); - dsiz = DBG_HDR_SIZE + - (sizeof(struct dll_sect) * dlthis->allocated_secn_count) + - BYTE_TO_HOST_ROUND(dlthis->debug_string_size + 1); - if (dsiz > siz) - siz = dsiz; /* larger of symbols and .dllview temp */ - sp = (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym, - siz); - if (!sp) { - DL_ERROR(err_alloc, siz); - return; - } - dlthis->local_symtab = sp; - /* Read the symbols in the input, store them in the table, and post any - * globals to the global symbol table. In the process, externals - become defined from the global symbol table */ - checks = dlthis->verify.dv_sym_tab_checksum; - symbols_left = sym_count; - - my_sym_buf = kzalloc(sizeof(*my_sym_buf) * MY_SYM_BUF_SIZ, GFP_KERNEL); - if (!my_sym_buf) - return; - - do { /* read all symbols */ - char *sname; - u32 val; - s32 delta; - struct doff_syment_t *input_sym; - unsigned syms_in_buf; - - input_sym = my_sym_buf; - syms_in_buf = symbols_left > MY_SYM_BUF_SIZ ? - MY_SYM_BUF_SIZ : symbols_left; - siz = syms_in_buf * sizeof(struct doff_syment_t); - if (dlthis->strm->read_buffer(dlthis->strm, input_sym, siz) != - siz) { - DL_ERROR(readstrm, sym_errid); - goto free_sym_buf; - } - if (dlthis->reorder_map) - dload_reorder(input_sym, siz, dlthis->reorder_map); - - checks += dload_checksum(input_sym, siz); - do { /* process symbols in buffer */ - symbols_left -= 1; - /* attempt to derive the name of this symbol */ - sname = NULL; - if (input_sym->dn_offset > 0) { -#if BITS_PER_AU <= BITS_PER_BYTE - if ((u32) input_sym->dn_offset < - dlthis->dfile_hdr.df_strtab_size) - sname = dlthis->str_head + - BYTE_TO_HOST(input_sym->dn_offset); - else - dload_error(dlthis, - "Bad name offset in symbol " - " %d", symbols_left); -#else - sname = unpack_name(dlthis, - input_sym->dn_offset); -#endif - } - val = input_sym->dn_value; - delta = 0; - sp->sclass = input_sym->dn_sclass; - sp->secnn = input_sym->dn_scnum; - /* if this is an undefined symbol, - * define it (or fail) now */ - if (sp->secnn == DN_UNDEF) { - /* pointless for static undefined */ - if (input_sym->dn_sclass != DN_EXT) - goto loop_cont; - - /* try to define symbol from previously - * loaded images */ - symp = dlthis->mysym->find_matching_symbol - (dlthis->mysym, sname); - if (!symp) { - DL_ERROR - ("Undefined external symbol %s", - sname); - goto loop_cont; - } - val = delta = symp->value; -#ifdef ENABLE_TRAMP_DEBUG - dload_syms_error(dlthis->mysym, - "===> ext sym [%s] at %x", - sname, val); -#endif - - goto loop_cont; - } - /* symbol defined by this module */ - if (sp->secnn > 0) { - /* symbol references a section */ - if ((unsigned)sp->secnn <= - dlthis->allocated_secn_count) { - /* section was allocated */ - struct doff_scnhdr_t *srefp = - &dlthis->sect_hdrs[sp->secnn - 1]; - - if (input_sym->dn_sclass == - DN_STATLAB || - input_sym->dn_sclass == DN_EXTLAB) { - /* load */ - delta = srefp->ds_vaddr; - } else { - /* run */ - delta = srefp->ds_paddr; - } - val += delta; - } - goto loop_itr; - } - /* This symbol is an absolute symbol */ - if (sp->secnn == DN_ABS && ((sp->sclass == DN_EXT) || - (sp->sclass == - DN_EXTLAB))) { - symp = - dlthis->mysym->find_matching_symbol(dlthis-> - mysym, - sname); - if (!symp) - goto loop_itr; - /* This absolute symbol is already defined. */ - if (symp->value == input_sym->dn_value) { - /* If symbol values are equal, continue - * but don't add to the global symbol - * table */ - sp->value = val; - sp->delta = delta; - sp += 1; - input_sym += 1; - continue; - } else { - /* If symbol values are not equal, - * return with redefinition error */ - DL_ERROR("Absolute symbol %s is " - "defined multiple times with " - "different values", sname); - goto free_sym_buf; - } - } -loop_itr: - /* if this is a global symbol, post it to the - * global table */ - if (input_sym->dn_sclass == DN_EXT || - input_sym->dn_sclass == DN_EXTLAB) { - /* Keep this global symbol for subsequent - * modules. Don't complain on error, to allow - * symbol API to suppress global symbols */ - if (!sname) - goto loop_cont; - - newsym = dlthis->mysym->add_to_symbol_table - (dlthis->mysym, sname, - (unsigned)dlthis->myhandle); - if (newsym) - newsym->value = val; - - } /* global */ -loop_cont: - sp->value = val; - sp->delta = delta; - sp += 1; - input_sym += 1; - } while ((syms_in_buf -= 1) > 0); /* process sym in buf */ - } while (symbols_left > 0); /* read all symbols */ - if (~checks) - dload_error(dlthis, "Checksum of symbols failed"); - -free_sym_buf: - kfree(my_sym_buf); - return; -} /* dload_symbols */ - -/***************************************************************************** - * Procedure symbol_table_free - * - * Parameters: - * none - * - * Effect: - * Frees any state used by the symbol table. - * - * WARNING: - * This routine is not allowed to declare errors! - **************************************************************************** */ -static void symbol_table_free(struct dload_state *dlthis) -{ - if (dlthis->local_symtab) { - if (dlthis->dload_errcount) { /* blow off our symbols */ - dlthis->mysym->purge_symbol_table(dlthis->mysym, - (unsigned) - dlthis->myhandle); - } - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->local_symtab); - } -} /* symbol_table_free */ - -/* .cinit Processing - * - * The dynamic loader does .cinit interpretation. cload_cinit() - * acts as a special write-to-target function, in that it takes relocated - * data from the normal data flow, and interprets it as .cinit actions. - * Because the normal data flow does not necessarily process the whole - * .cinit section in one buffer, cload_cinit() must be prepared to - * interpret the data piecemeal. A state machine is used for this - * purpose. - */ - -/* The following are only for use by reloc.c and things it calls */ -static const struct ldr_section_info cinit_info_init = { cinitname, 0, 0, - (ldr_addr)-1, 0, DLOAD_BSS, 0 -}; - -/************************************************************************* - * Procedure cload_cinit - * - * Parameters: - * ipacket Pointer to data packet to be loaded - * - * Effect: - * Interprets the data in the buffer as .cinit data, and performs the - * appropriate initializations. - *********************************************************************** */ -static void cload_cinit(struct dload_state *dlthis, - struct image_packet_t *ipacket) -{ -#if TDATA_TO_HOST(CINIT_COUNT)*BITS_PER_AU > 16 - s32 init_count, left; -#else - s16 init_count, left; -#endif - unsigned char *pktp = ipacket->img_data; - unsigned char *pktend = pktp + BYTE_TO_HOST_ROUND(ipacket->packet_size); - int temp; - ldr_addr atmp; - struct ldr_section_info cinit_info; - - /* PROCESS ALL THE INITIALIZATION RECORDS THE BUFFER. */ - while (true) { - left = pktend - pktp; - switch (dlthis->cinit_state) { - case CI_COUNT: /* count field */ - if (left < TDATA_TO_HOST(CINIT_COUNT)) - goto loopexit; - temp = dload_unpack(dlthis, (tgt_au_t *) pktp, - CINIT_COUNT * TDATA_AU_BITS, 0, - ROP_SGN); - pktp += TDATA_TO_HOST(CINIT_COUNT); - /* negative signifies BSS table, zero means done */ - if (temp <= 0) { - dlthis->cinit_state = CI_DONE; - break; - } - dlthis->cinit_count = temp; - dlthis->cinit_state = CI_ADDRESS; - break; -#if CINIT_ALIGN < CINIT_ADDRESS - case CI_PARTADDRESS: - pktp -= TDATA_TO_HOST(CINIT_ALIGN); - /* back up pointer into space courtesy of caller */ - *(uint16_t *) pktp = dlthis->cinit_addr; - /* stuff in saved bits !! FALL THRU !! */ -#endif - case CI_ADDRESS: /* Address field for a copy packet */ - if (left < TDATA_TO_HOST(CINIT_ADDRESS)) { -#if CINIT_ALIGN < CINIT_ADDRESS - if (left == TDATA_TO_HOST(CINIT_ALIGN)) { - /* address broken into halves */ - dlthis->cinit_addr = *(uint16_t *) pktp; - /* remember 1st half */ - dlthis->cinit_state = CI_PARTADDRESS; - left = 0; - } -#endif - goto loopexit; - } - atmp = dload_unpack(dlthis, (tgt_au_t *) pktp, - CINIT_ADDRESS * TDATA_AU_BITS, 0, - ROP_UNS); - pktp += TDATA_TO_HOST(CINIT_ADDRESS); -#if CINIT_PAGE_BITS > 0 - dlthis->cinit_page = atmp & - ((1 << CINIT_PAGE_BITS) - 1); - atmp >>= CINIT_PAGE_BITS; -#else - dlthis->cinit_page = CINIT_DEFAULT_PAGE; -#endif - dlthis->cinit_addr = atmp; - dlthis->cinit_state = CI_COPY; - break; - case CI_COPY: /* copy bits to the target */ - init_count = HOST_TO_TDATA(left); - if (init_count > dlthis->cinit_count) - init_count = dlthis->cinit_count; - if (init_count == 0) - goto loopexit; /* get more bits */ - cinit_info = cinit_info_init; - cinit_info.page = dlthis->cinit_page; - if (!dlthis->myio->writemem(dlthis->myio, pktp, - TDATA_TO_TADDR - (dlthis->cinit_addr), - &cinit_info, - TDATA_TO_HOST(init_count))) { - dload_error(dlthis, initfail, "write", - dlthis->cinit_addr); - } - dlthis->cinit_count -= init_count; - if (dlthis->cinit_count <= 0) { - dlthis->cinit_state = CI_COUNT; - init_count = (init_count + CINIT_ALIGN - 1) & - -CINIT_ALIGN; - /* align to next init */ - } - pktp += TDATA_TO_HOST(init_count); - dlthis->cinit_addr += init_count; - break; - case CI_DONE: /* no more .cinit to do */ - return; - } /* switch (cinit_state) */ - } /* while */ - -loopexit: - if (left > 0) { - dload_error(dlthis, "%d bytes left over in cinit packet", left); - dlthis->cinit_state = CI_DONE; /* left over bytes are bad */ - } -} /* cload_cinit */ - -/* Functions to interface to reloc.c - * - * reloc.c is the relocation module borrowed from the linker, with - * minimal (we hope) changes for our purposes. cload_sect_data() invokes - * this module on a section to relocate and load the image data for that - * section. The actual read and write actions are supplied by the global - * routines below. - */ - -/************************************************************************ - * Procedure relocate_packet - * - * Parameters: - * ipacket Pointer to an image packet to relocate - * - * Effect: - * Performs the required relocations on the packet. Returns a checksum - * of the relocation operations. - *********************************************************************** */ -#define MY_RELOC_BUF_SIZ 8 -/* careful! exists at the same time as the image buffer */ -static int relocate_packet(struct dload_state *dlthis, - struct image_packet_t *ipacket, - u32 *checks, bool *tramps_generated) -{ - u32 rnum; - *tramps_generated = false; - - rnum = ipacket->num_relocs; - do { /* all relocs */ - unsigned rinbuf; - int siz; - struct reloc_record_t *rp, rrec[MY_RELOC_BUF_SIZ]; - rp = rrec; - rinbuf = rnum > MY_RELOC_BUF_SIZ ? MY_RELOC_BUF_SIZ : rnum; - siz = rinbuf * sizeof(struct reloc_record_t); - if (dlthis->strm->read_buffer(dlthis->strm, rp, siz) != siz) { - DL_ERROR(readstrm, "relocation"); - return 0; - } - /* reorder the bytes if need be */ - if (dlthis->reorder_map) - dload_reorder(rp, siz, dlthis->reorder_map); - - *checks += dload_checksum(rp, siz); - do { - /* perform the relocation operation */ - dload_relocate(dlthis, (tgt_au_t *) ipacket->img_data, - rp, tramps_generated, false); - rp += 1; - rnum -= 1; - } while ((rinbuf -= 1) > 0); - } while (rnum > 0); /* all relocs */ - /* If trampoline(s) were generated, we need to do an update of the - * trampoline copy of the packet since a 2nd phase relo will be done - * later. */ - if (*tramps_generated == true) { - dload_tramp_pkt_udpate(dlthis, - (dlthis->image_secn - - dlthis->ldr_sections), - dlthis->image_offset, ipacket); - } - - return 1; -} /* dload_read_reloc */ - -#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32)) - -/* VERY dangerous */ -static const char imagepak[] = { "image packet" }; - -struct img_buffer { - struct image_packet_t ipacket; - u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)]; -}; - -/************************************************************************* - * Procedure dload_data - * - * Parameters: - * none - * - * Effect: - * Read image data from input file, relocate it, and download it to the - * target. - *********************************************************************** */ -static void dload_data(struct dload_state *dlthis) -{ - u16 curr_sect; - struct doff_scnhdr_t *sptr = dlthis->sect_hdrs; - struct ldr_section_info *lptr = dlthis->ldr_sections; - struct img_buffer *ibuf; - u8 *dest; - - /* Indicates whether CINIT processing has occurred */ - bool cinit_processed = false; - - ibuf = kzalloc(sizeof(*ibuf), GFP_KERNEL); - if (!ibuf) - return; - - /* Loop through the sections and load them one at a time. - */ - for (curr_sect = 0; curr_sect < dlthis->dfile_hdr.df_no_scns; - curr_sect += 1) { - if (ds_needs_download(sptr)) { - s32 nip; - ldr_addr image_offset = 0; - /* set relocation info for this section */ - if (curr_sect < dlthis->allocated_secn_count) - dlthis->delta_runaddr = sptr->ds_paddr; - else { - lptr = (struct ldr_section_info *)sptr; - dlthis->delta_runaddr = 0; - } - dlthis->image_secn = lptr; -#if BITS_PER_AU > BITS_PER_BYTE - lptr->name = unpack_name(dlthis, sptr->ds_offset); -#endif - nip = sptr->ds_nipacks; - while ((nip -= 1) >= 0) { /* process packets */ - - s32 ipsize; - u32 checks; - bool tramp_generated = false; - - /* get the fixed header bits */ - if (dlthis->strm->read_buffer(dlthis->strm, - &ibuf->ipacket, - IPH_SIZE) != - IPH_SIZE) { - DL_ERROR(readstrm, imagepak); - goto free_ibuf; - } - /* reorder the header if need be */ - if (dlthis->reorder_map) { - dload_reorder(&ibuf->ipacket, IPH_SIZE, - dlthis->reorder_map); - } - /* now read the rest of the packet */ - ipsize = - BYTE_TO_HOST(DOFF_ALIGN - (ibuf->ipacket.packet_size)); - if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) { - DL_ERROR("Bad image packet size %d", - ipsize); - goto free_ibuf; - } - dest = ibuf->bufr; - /* End of determination */ - - if (dlthis->strm->read_buffer(dlthis->strm, - ibuf->bufr, - ipsize) != - ipsize) { - DL_ERROR(readstrm, imagepak); - goto free_ibuf; - } - ibuf->ipacket.img_data = dest; - - /* reorder the bytes if need be */ -#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16) - if (dlthis->reorder_map) { - dload_reorder(dest, ipsize, - dlthis->reorder_map); - } - checks = dload_checksum(dest, ipsize); -#else - if (dlthis->dfile_hdr.df_byte_reshuffle != - TARGET_ORDER(REORDER_MAP - (BYTE_RESHUFFLE_VALUE))) { - /* put image bytes in big-endian order, - * not PC order */ - dload_reorder(dest, ipsize, - TARGET_ORDER - (dlthis->dfile_hdr. - df_byte_reshuffle)); - } -#if TARGET_AU_BITS > 8 - checks = dload_reverse_checksum16(dest, ipsize); -#else - checks = dload_reverse_checksum(dest, ipsize); -#endif -#endif - - checks += dload_checksum(&ibuf->ipacket, - IPH_SIZE); - /* relocate the image bits as needed */ - if (ibuf->ipacket.num_relocs) { - dlthis->image_offset = image_offset; - if (!relocate_packet(dlthis, - &ibuf->ipacket, - &checks, - &tramp_generated)) - goto free_ibuf; /* error */ - } - if (~checks) - DL_ERROR(err_checksum, imagepak); - /* Only write the result to the target if no - * trampoline was generated. Otherwise it - *will be done during trampoline finalize. */ - - if (tramp_generated == false) { - - /* stuff the result into target - * memory */ - if (dload_check_type(sptr, - DLOAD_CINIT)) { - cload_cinit(dlthis, - &ibuf->ipacket); - cinit_processed = true; - } else { - /* FIXME */ - if (!dlthis->myio-> - writemem(dlthis-> - myio, - ibuf->bufr, - lptr-> - load_addr + - image_offset, - lptr, - BYTE_TO_HOST - (ibuf-> - ipacket. - packet_size))) { - DL_ERROR - ("Write to " - FMT_UI32 - " failed", - lptr-> - load_addr + - image_offset); - } - } - } - image_offset += - BYTE_TO_TADDR(ibuf->ipacket.packet_size); - } /* process packets */ - /* if this is a BSS section, we may want to fill it */ - if (!dload_check_type(sptr, DLOAD_BSS)) - goto loop_cont; - - if (!(dlthis->myoptions & DLOAD_INITBSS)) - goto loop_cont; - - if (cinit_processed) { - /* Don't clear BSS after load-time - * initialization */ - DL_ERROR - ("Zero-initialization at " FMT_UI32 - " after " "load-time initialization!", - lptr->load_addr); - goto loop_cont; - } - /* fill the .bss area */ - dlthis->myio->fillmem(dlthis->myio, - TADDR_TO_HOST(lptr->load_addr), - lptr, TADDR_TO_HOST(lptr->size), - DLOAD_FILL_BSS); - goto loop_cont; - } - /* if DS_DOWNLOAD_MASK */ - /* If not loading, but BSS, zero initialize */ - if (!dload_check_type(sptr, DLOAD_BSS)) - goto loop_cont; - - if (!(dlthis->myoptions & DLOAD_INITBSS)) - goto loop_cont; - - if (curr_sect >= dlthis->allocated_secn_count) - lptr = (struct ldr_section_info *)sptr; - - if (cinit_processed) { - /*Don't clear BSS after load-time initialization */ - DL_ERROR("Zero-initialization at " FMT_UI32 - " attempted after " - "load-time initialization!", lptr->load_addr); - goto loop_cont; - } - /* fill the .bss area */ - dlthis->myio->fillmem(dlthis->myio, - TADDR_TO_HOST(lptr->load_addr), lptr, - TADDR_TO_HOST(lptr->size), - DLOAD_FILL_BSS); -loop_cont: - sptr += 1; - lptr += 1; - } /* load sections */ - - /* Finalize any trampolines that were created during the load */ - if (dload_tramp_finalize(dlthis) == 0) { - DL_ERROR("Finalization of auto-trampolines (size = " FMT_UI32 - ") failed", dlthis->tramp.tramp_sect_next_addr); - } -free_ibuf: - kfree(ibuf); - return; -} /* dload_data */ - -/************************************************************************* - * Procedure dload_reorder - * - * Parameters: - * data 32-bit aligned pointer to data to be byte-swapped - * dsiz size of the data to be reordered in sizeof() units. - * map 32-bit map defining how to reorder the data. Value - * must be REORDER_MAP() of some permutation - * of 0x00 01 02 03 - * - * Effect: - * Re-arranges the bytes in each word according to the map specified. - * - *********************************************************************** */ -/* mask for byte shift count */ -#define SHIFT_COUNT_MASK (3 << LOG_BITS_PER_BYTE) - -void dload_reorder(void *data, int dsiz, unsigned int map) -{ - register u32 tmp, tmap, datv; - u32 *dp = (u32 *) data; - - map <<= LOG_BITS_PER_BYTE; /* align map with SHIFT_COUNT_MASK */ - do { - tmp = 0; - datv = *dp; - tmap = map; - do { - tmp |= (datv & BYTE_MASK) << (tmap & SHIFT_COUNT_MASK); - tmap >>= BITS_PER_BYTE; - } while (datv >>= BITS_PER_BYTE); - *dp++ = tmp; - } while ((dsiz -= sizeof(u32)) > 0); -} /* dload_reorder */ - -/************************************************************************* - * Procedure dload_checksum - * - * Parameters: - * data 32-bit aligned pointer to data to be checksummed - * siz size of the data to be checksummed in sizeof() units. - * - * Effect: - * Returns a checksum of the specified block - * - *********************************************************************** */ -u32 dload_checksum(void *data, unsigned siz) -{ - u32 sum; - u32 *dp; - int left; - - sum = 0; - dp = (u32 *) data; - for (left = siz; left > 0; left -= sizeof(u32)) - sum += *dp++; - return sum; -} /* dload_checksum */ - -#if HOST_ENDIANNESS -/************************************************************************* - * Procedure dload_reverse_checksum - * - * Parameters: - * data 32-bit aligned pointer to data to be checksummed - * siz size of the data to be checksummed in sizeof() units. - * - * Effect: - * Returns a checksum of the specified block, which is assumed to be bytes - * in big-endian order. - * - * Notes: - * In a big-endian host, things like the string table are stored as bytes - * in host order. But dllcreate always checksums in little-endian order. - * It is most efficient to just handle the difference a word at a time. - * - ********************************************************************** */ -u32 dload_reverse_checksum(void *data, unsigned siz) -{ - u32 sum, temp; - u32 *dp; - int left; - - sum = 0; - dp = (u32 *) data; - - for (left = siz; left > 0; left -= sizeof(u32)) { - temp = *dp++; - sum += temp << BITS_PER_BYTE * 3; - sum += temp >> BITS_PER_BYTE * 3; - sum += (temp >> BITS_PER_BYTE) & (BYTE_MASK << BITS_PER_BYTE); - sum += (temp & (BYTE_MASK << BITS_PER_BYTE)) << BITS_PER_BYTE; - } - - return sum; -} /* dload_reverse_checksum */ - -#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32) -u32 dload_reverse_checksum16(void *data, unsigned siz) -{ - uint_fast32_t sum, temp; - u32 *dp; - int left; - - sum = 0; - dp = (u32 *) data; - - for (left = siz; left > 0; left -= sizeof(u32)) { - temp = *dp++; - sum += temp << BITS_PER_BYTE * 2; - sum += temp >> BITS_PER_BYTE * 2; - } - - return sum; -} /* dload_reverse_checksum16 */ -#endif -#endif - -/************************************************************************* - * Procedure swap_words - * - * Parameters: - * data 32-bit aligned pointer to data to be swapped - * siz size of the data to be swapped. - * bitmap Bit map of how to swap each 32-bit word; 1 => 2 shorts, - * 0 => 1 long - * - * Effect: - * Swaps the specified data according to the specified map - * - *********************************************************************** */ -static void swap_words(void *data, unsigned siz, unsigned bitmap) -{ - register int i; -#if TARGET_AU_BITS < 16 - register u16 *sp; -#endif - register u32 *lp; - - siz /= sizeof(u16); - -#if TARGET_AU_BITS < 16 - /* pass 1: do all the bytes */ - i = siz; - sp = (u16 *) data; - do { - register u16 tmp; - tmp = *sp; - *sp++ = SWAP16BY8(tmp); - } while ((i -= 1) > 0); -#endif - -#if TARGET_AU_BITS < 32 - /* pass 2: fixup the 32-bit words */ - i = siz >> 1; - lp = (u32 *) data; - do { - if ((bitmap & 1) == 0) { - register u32 tmp; - tmp = *lp; - *lp = SWAP32BY16(tmp); - } - lp += 1; - bitmap >>= 1; - } while ((i -= 1) > 0); -#endif -} /* swap_words */ - -/************************************************************************* - * Procedure copy_tgt_strings - * - * Parameters: - * dstp Destination address. Assumed to be 32-bit aligned - * srcp Source address. Assumed to be 32-bit aligned - * charcount Number of characters to copy. - * - * Effect: - * Copies strings from the source (which is in usual .dof file order on - * the loading processor) to the destination buffer (which should be in proper - * target addressable unit order). Makes sure the last string in the - * buffer is NULL terminated (for safety). - * Returns the first unused destination address. - *********************************************************************** */ -static char *copy_tgt_strings(void *dstp, void *srcp, unsigned charcount) -{ - register tgt_au_t *src = (tgt_au_t *) srcp; - register tgt_au_t *dst = (tgt_au_t *) dstp; - register int cnt = charcount; - do { -#if TARGET_AU_BITS <= BITS_PER_AU - /* byte-swapping issues may exist for strings on target */ - *dst++ = *src++; -#else - *dst++ = *src++; -#endif - } while ((cnt -= (sizeof(tgt_au_t) * BITS_PER_AU / BITS_PER_BYTE)) > 0); - /*apply force to make sure that the string table has null terminator */ -#if (BITS_PER_AU == BITS_PER_BYTE) && (TARGET_AU_BITS == BITS_PER_BYTE) - dst[-1] = 0; -#else - /* little endian */ - dst[-1] &= (1 << (BITS_PER_AU - BITS_PER_BYTE)) - 1; -#endif - return (char *)dst; -} /* copy_tgt_strings */ - -/************************************************************************* - * Procedure init_module_handle - * - * Parameters: - * none - * - * Effect: - * Initializes the module handle we use to enable unloading, and installs - * the debug information required by the target. - * - * Notes: - * The handle returned from dynamic_load_module needs to encapsulate all the - * allocations done for the module, and enable them plus the modules symbols to - * be deallocated. - * - *********************************************************************** */ -#ifndef _BIG_ENDIAN -static const struct ldr_section_info dllview_info_init = { ".dllview", 0, 0, - (ldr_addr)-1, DBG_LIST_PAGE, DLOAD_DATA, 0 -}; -#else -static const struct ldr_section_info dllview_info_init = { ".dllview", 0, 0, - (ldr_addr)-1, DLOAD_DATA, DBG_LIST_PAGE, 0 -}; -#endif -static void init_module_handle(struct dload_state *dlthis) -{ - struct my_handle *hndl; - u16 curr_sect; - struct ldr_section_info *asecs; - struct dll_module *dbmod; - struct dll_sect *dbsec; - struct dbg_mirror_root *mlist; - register char *cp; - struct modules_header mhdr; - struct ldr_section_info dllview_info; - struct dynload_symbol *debug_mirror_sym; - hndl = dlthis->myhandle; - if (!hndl) - return; /* must be errors detected, so forget it */ - - /* Store the section count */ - hndl->secn_count = dlthis->allocated_secn_count; - - /* If a trampoline section was created, add it in */ - if (dlthis->tramp.tramp_sect_next_addr != 0) - hndl->secn_count += 1; - - hndl->secn_count = hndl->secn_count << 1; - - hndl->secn_count = dlthis->allocated_secn_count << 1; -#ifndef TARGET_ENDIANNESS - if (dlthis->big_e_target) - hndl->secn_count += 1; /* flag for big-endian */ -#endif - if (dlthis->dload_errcount) - return; /* abandon if errors detected */ - /* Locate the symbol that names the header for the CCS debug list - of modules. If not found, we just don't generate the debug record. - If found, we create our modules list. We make sure to create the - loader_dllview_root even if there is no relocation info to record, - just to try to put both symbols in the same symbol table and - module. */ - debug_mirror_sym = dlthis->mysym->find_matching_symbol(dlthis->mysym, - loader_dllview_root); - if (!debug_mirror_sym) { - struct dynload_symbol *dlmodsym; - struct dbg_mirror_root *mlst; - - /* our root symbol is not yet present; - check if we have DLModules defined */ - dlmodsym = dlthis->mysym->find_matching_symbol(dlthis->mysym, - LINKER_MODULES_HEADER); - if (!dlmodsym) - return; /* no DLModules list so no debug info */ - /* if we have DLModules defined, construct our header */ - mlst = (struct dbg_mirror_root *) - dlthis->mysym->dload_allocate(dlthis->mysym, - sizeof(struct - dbg_mirror_root)); - if (!mlst) { - DL_ERROR(err_alloc, sizeof(struct dbg_mirror_root)); - return; - } - mlst->next = NULL; - mlst->changes = 0; - mlst->refcount = 0; - mlst->dbthis = TDATA_TO_TADDR(dlmodsym->value); - /* add our root symbol */ - debug_mirror_sym = dlthis->mysym->add_to_symbol_table - (dlthis->mysym, loader_dllview_root, - (unsigned)dlthis->myhandle); - if (!debug_mirror_sym) { - /* failed, recover memory */ - dlthis->mysym->dload_deallocate(dlthis->mysym, mlst); - return; - } - debug_mirror_sym->value = (u32) mlst; - } - /* First create the DLLview record and stuff it into the buffer. - Then write it to the DSP. Record pertinent locations in our hndl, - and add it to the per-processor list of handles with debug info. */ -#ifndef DEBUG_HEADER_IN_LOADER - mlist = (struct dbg_mirror_root *)debug_mirror_sym->value; - if (!mlist) - return; -#else - mlist = (struct dbg_mirror_root *)&debug_list_header; -#endif - hndl->dm.root = mlist; /* set pointer to root into our handle */ - if (!dlthis->allocated_secn_count) - return; /* no load addresses to be recorded */ - /* reuse temporary symbol storage */ - dbmod = (struct dll_module *)dlthis->local_symtab; - /* Create the DLLview record in the memory we retain for our handle */ - dbmod->num_sects = dlthis->allocated_secn_count; - dbmod->timestamp = dlthis->verify.dv_timdat; - dbmod->version = INIT_VERSION; - dbmod->verification = VERIFICATION; - asecs = dlthis->ldr_sections; - dbsec = dbmod->sects; - for (curr_sect = dlthis->allocated_secn_count; - curr_sect > 0; curr_sect -= 1) { - dbsec->sect_load_adr = asecs->load_addr; - dbsec->sect_run_adr = asecs->run_addr; - dbsec += 1; - asecs += 1; - } - - /* If a trampoline section was created go ahead and add its info */ - if (dlthis->tramp.tramp_sect_next_addr != 0) { - dbmod->num_sects++; - dbsec->sect_load_adr = asecs->load_addr; - dbsec->sect_run_adr = asecs->run_addr; - dbsec++; - asecs++; - } - - /* now cram in the names */ - cp = copy_tgt_strings(dbsec, dlthis->str_head, - dlthis->debug_string_size); - - /* If a trampoline section was created, add its name so DLLView - * can show the user the section info. */ - if (dlthis->tramp.tramp_sect_next_addr != 0) { - cp = copy_tgt_strings(cp, - dlthis->tramp.final_string_table, - strlen(dlthis->tramp.final_string_table) + - 1); - } - - /* round off the size of the debug record, and remember same */ - hndl->dm.dbsiz = HOST_TO_TDATA_ROUND(cp - (char *)dbmod); - *cp = 0; /* strictly to make our test harness happy */ - dllview_info = dllview_info_init; - dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz); - /* Initialize memory context to default heap */ - dllview_info.context = 0; - hndl->dm.context = 0; - /* fill in next pointer and size */ - if (mlist->next) { - dbmod->next_module = TADDR_TO_TDATA(mlist->next->dm.dbthis); - dbmod->next_module_size = mlist->next->dm.dbsiz; - } else { - dbmod->next_module_size = 0; - dbmod->next_module = 0; - } - /* allocate memory for on-DSP DLLview debug record */ - if (!dlthis->myalloc) - return; - if (!dlthis->myalloc->dload_allocate(dlthis->myalloc, &dllview_info, - HOST_TO_TADDR(sizeof(u32)))) { - return; - } - /* Store load address of .dllview section */ - hndl->dm.dbthis = dllview_info.load_addr; - /* Store memory context (segid) in which .dllview section - * was allocated */ - hndl->dm.context = dllview_info.context; - mlist->refcount += 1; - /* swap bytes in the entire debug record, but not the string table */ - if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) { - swap_words(dbmod, (char *)dbsec - (char *)dbmod, - DLL_MODULE_BITMAP); - } - /* Update the DLLview list on the DSP write new record */ - if (!dlthis->myio->writemem(dlthis->myio, dbmod, - dllview_info.load_addr, &dllview_info, - TADDR_TO_HOST(dllview_info.size))) { - return; - } - /* write new header */ - mhdr.first_module_size = hndl->dm.dbsiz; - mhdr.first_module = TADDR_TO_TDATA(dllview_info.load_addr); - /* swap bytes in the module header, if needed */ - if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) { - swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16), - MODULES_HEADER_BITMAP); - } - dllview_info = dllview_info_init; - if (!dlthis->myio->writemem(dlthis->myio, &mhdr, mlist->dbthis, - &dllview_info, - sizeof(struct modules_header) - - sizeof(u16))) { - return; - } - /* Add the module handle to this processor's list - of handles with debug info */ - hndl->dm.next = mlist->next; - if (hndl->dm.next) - hndl->dm.next->dm.prev = hndl; - hndl->dm.prev = (struct my_handle *)mlist; - mlist->next = hndl; /* insert after root */ -} /* init_module_handle */ - -/************************************************************************* - * Procedure dynamic_unload_module - * - * Parameters: - * mhandle A module handle from dynamic_load_module - * syms Host-side symbol table and malloc/free functions - * alloc Target-side memory allocation - * - * Effect: - * The module specified by mhandle is unloaded. Unloading causes all - * target memory to be deallocated, all symbols defined by the module to - * be purged, and any host-side storage used by the dynamic loader for - * this module to be released. - * - * Returns: - * Zero for success. On error, the number of errors detected is returned. - * Individual errors are reported using syms->error_report(). - *********************************************************************** */ -int dynamic_unload_module(void *mhandle, - struct dynamic_loader_sym *syms, - struct dynamic_loader_allocate *alloc, - struct dynamic_loader_initialize *init) -{ - s16 curr_sect; - struct ldr_section_info *asecs; - struct my_handle *hndl; - struct dbg_mirror_root *root; - unsigned errcount = 0; - struct ldr_section_info dllview_info = dllview_info_init; - struct modules_header mhdr; - - hndl = (struct my_handle *)mhandle; - if (!hndl) - return 0; /* if handle is null, nothing to do */ - /* Clear out the module symbols - * Note that if this is the module that defined MODULES_HEADER - (the head of the target debug list) - * then this operation will blow away that symbol. - It will therefore be impossible for subsequent - * operations to add entries to this un-referenceable list. */ - if (!syms) - return 1; - syms->purge_symbol_table(syms, (unsigned)hndl); - /* Deallocate target memory for sections - * NOTE: The trampoline section, if created, gets deleted here, too */ - - asecs = hndl->secns; - if (alloc) - for (curr_sect = (hndl->secn_count >> 1); curr_sect > 0; - curr_sect -= 1) { - asecs->name = NULL; - alloc->dload_deallocate(alloc, asecs++); - } - root = hndl->dm.root; - if (!root) { - /* there is a debug list containing this module */ - goto func_end; - } - if (!hndl->dm.dbthis) { /* target-side dllview record exists */ - goto loop_end; - } - /* Retrieve memory context in which .dllview was allocated */ - dllview_info.context = hndl->dm.context; - if (hndl->dm.prev == hndl) - goto exitunltgt; - - /* target-side dllview record is in list */ - /* dequeue this record from our GPP-side mirror list */ - hndl->dm.prev->dm.next = hndl->dm.next; - if (hndl->dm.next) - hndl->dm.next->dm.prev = hndl->dm.prev; - /* Update next_module of previous entry in target list - * We are using mhdr here as a surrogate for either a - struct modules_header or a dll_module */ - if (hndl->dm.next) { - mhdr.first_module = TADDR_TO_TDATA(hndl->dm.next->dm.dbthis); - mhdr.first_module_size = hndl->dm.next->dm.dbsiz; - } else { - mhdr.first_module = 0; - mhdr.first_module_size = 0; - } - if (!init) - goto exitunltgt; - - if (!init->connect(init)) { - dload_syms_error(syms, iconnect); - errcount += 1; - goto exitunltgt; - } - /* swap bytes in the module header, if needed */ - if (TARGET_ENDIANNESS_DIFFERS(hndl->secn_count & 0x1)) { - swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16), - MODULES_HEADER_BITMAP); - } - if (!init->writemem(init, &mhdr, hndl->dm.prev->dm.dbthis, - &dllview_info, sizeof(struct modules_header) - - sizeof(mhdr.update_flag))) { - dload_syms_error(syms, dlvwrite); - errcount += 1; - } - /* update change counter */ - root->changes += 1; - if (!init->writemem(init, &(root->changes), - root->dbthis + HOST_TO_TADDR - (sizeof(mhdr.first_module) + - sizeof(mhdr.first_module_size)), - &dllview_info, sizeof(mhdr.update_flag))) { - dload_syms_error(syms, dlvwrite); - errcount += 1; - } - init->release(init); -exitunltgt: - /* release target storage */ - dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz); - dllview_info.load_addr = hndl->dm.dbthis; - if (alloc) - alloc->dload_deallocate(alloc, &dllview_info); - root->refcount -= 1; - /* target-side dllview record exists */ -loop_end: -#ifndef DEBUG_HEADER_IN_LOADER - if (root->refcount <= 0) { - /* if all references gone, blow off the header */ - /* our root symbol may be gone due to the Purge above, - but if not, do not destroy the root */ - if (syms->find_matching_symbol - (syms, loader_dllview_root) == NULL) - syms->dload_deallocate(syms, root); - } -#endif -func_end: - /* there is a debug list containing this module */ - syms->dload_deallocate(syms, mhandle); /* release our storage */ - return errcount; -} /* dynamic_unload_module */ - -#if BITS_PER_AU > BITS_PER_BYTE -/************************************************************************* - * Procedure unpack_name - * - * Parameters: - * soffset Byte offset into the string table - * - * Effect: - * Returns a pointer to the string specified by the offset supplied, or - * NULL for error. - * - *********************************************************************** */ -static char *unpack_name(struct dload_state *dlthis, u32 soffset) -{ - u8 tmp, *src; - char *dst; - - if (soffset >= dlthis->dfile_hdr.df_strtab_size) { - dload_error(dlthis, "Bad string table offset " FMT_UI32, - soffset); - return NULL; - } - src = (uint_least8_t *) dlthis->str_head + - (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)); - dst = dlthis->str_temp; - if (soffset & 1) - *dst++ = *src++; /* only 1 character in first word */ - do { - tmp = *src++; - *dst = (tmp >> BITS_PER_BYTE); - if (!(*dst++)) - break; - } while ((*dst++ = tmp & BYTE_MASK)); - dlthis->temp_len = dst - dlthis->str_temp; - /* squirrel away length including terminating null */ - return dlthis->str_temp; -} /* unpack_name */ -#endif diff --git a/drivers/staging/tidspbridge/dynload/dload_internal.h b/drivers/staging/tidspbridge/dynload/dload_internal.h deleted file mode 100644 index b9d079b96190..000000000000 --- a/drivers/staging/tidspbridge/dynload/dload_internal.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * dload_internal.h - * - * 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. - */ - -#ifndef _DLOAD_INTERNAL_ -#define _DLOAD_INTERNAL_ - -#include <linux/types.h> - -/* - * Internal state definitions for the dynamic loader - */ - -/* type used for relocation intermediate results */ -typedef s32 rvalue; - -/* unsigned version of same; must have at least as many bits */ -typedef u32 urvalue; - -/* - * Dynamic loader configuration constants - */ -/* error issued if input has more sections than this limit */ -#define REASONABLE_SECTION_LIMIT 100 - -/* (Addressable unit) value used to clear BSS section */ -#define DLOAD_FILL_BSS 0 - -/* - * Reorder maps explained (?) - * - * The doff file format defines a 32-bit pattern used to determine the - * byte order of an image being read. That value is - * BYTE_RESHUFFLE_VALUE == 0x00010203 - * For purposes of the reorder routine, we would rather have the all-is-OK - * for 32-bits pattern be 0x03020100. This first macro makes the - * translation from doff file header value to MAP value: */ -#define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303) -/* This translation is made in dload_headers. Thereafter, the all-is-OK - * value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE). - * But sadly, not all bits of the doff file are 32-bit integers. - * The notable exceptions are strings and image bits. - * Strings obey host byte order: */ -#if defined(_BIG_ENDIAN) -#define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303) -#else -#define HOST_BYTE_ORDER(cookedmap) (cookedmap) -#endif -/* Target bits consist of target AUs (could be bytes, or 16-bits, - * or 32-bits) stored as an array in host order. A target order - * map is defined by: */ -#if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16 -#define TARGET_ORDER(cookedmap) (cookedmap) -#elif TARGET_AU_BITS > 8 -#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202) -#else -#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303) -#endif - -/* forward declaration for handle returned by dynamic loader */ -struct my_handle; - -/* - * a list of module handles, which mirrors the debug list on the target - */ -struct dbg_mirror_root { - /* must be same as dbg_mirror_list; __DLModules address on target */ - u32 dbthis; - struct my_handle *next; /* must be same as dbg_mirror_list */ - u16 changes; /* change counter */ - u16 refcount; /* number of modules referencing this root */ -}; - -struct dbg_mirror_list { - u32 dbthis; - struct my_handle *next, *prev; - struct dbg_mirror_root *root; - u16 dbsiz; - u32 context; /* Save context for .dllview memory allocation */ -}; - -#define VARIABLE_SIZE 1 -/* - * the structure we actually return as an opaque module handle - */ -struct my_handle { - struct dbg_mirror_list dm; /* !!! must be first !!! */ - /* sections following << 1, LSB is set for big-endian target */ - u16 secn_count; - struct ldr_section_info secns[VARIABLE_SIZE]; -}; -#define MY_HANDLE_SIZE (sizeof(struct my_handle) -\ - sizeof(struct ldr_section_info)) -/* real size of my_handle */ - -/* - * reduced symbol structure used for symbols during relocation - */ -struct local_symbol { - s32 value; /* Relocated symbol value */ - s32 delta; /* Original value in input file */ - s16 secnn; /* section number */ - s16 sclass; /* symbol class */ -}; - -/* - * Trampoline data structures - */ -#define TRAMP_NO_GEN_AVAIL 65535 -#define TRAMP_SYM_PREFIX "__$dbTR__" -#define TRAMP_SECT_NAME ".dbTR" -/* MUST MATCH THE LENGTH ABOVE!! */ -#define TRAMP_SYM_PREFIX_LEN 9 -/* Includes NULL termination */ -#define TRAMP_SYM_HEX_ASCII_LEN 9 - -#define GET_CONTAINER(ptr, type, field) ((type *)((unsigned long)ptr -\ - (unsigned long)(&((type *)0)->field))) -#ifndef FIELD_OFFSET -#define FIELD_OFFSET(type, field) ((unsigned long)(&((type *)0)->field)) -#endif - -/* - The trampoline code for the target is located in a table called - "tramp_gen_info" with is indexed by looking up the index in the table - "tramp_map". The tramp_map index is acquired using the target - HASH_FUNC on the relocation type that caused the trampoline. Each - trampoline code table entry MUST follow this format: - - |----------------------------------------------| - | tramp_gen_code_hdr | - |----------------------------------------------| - | Trampoline image code | - | (the raw instruction code for the target) | - |----------------------------------------------| - | Relocation entries for the image code | - |----------------------------------------------| - - This is very similar to how image data is laid out in the DOFF file - itself. - */ -struct tramp_gen_code_hdr { - u32 tramp_code_size; /* in BYTES */ - u32 num_relos; - u32 relo_offset; /* in BYTES */ -}; - -struct tramp_img_pkt { - struct tramp_img_pkt *next; /* MUST BE FIRST */ - u32 base; - struct tramp_gen_code_hdr hdr; - u8 payload[VARIABLE_SIZE]; -}; - -struct tramp_img_dup_relo { - struct tramp_img_dup_relo *next; - struct reloc_record_t relo; -}; - -struct tramp_img_dup_pkt { - struct tramp_img_dup_pkt *next; /* MUST BE FIRST */ - s16 secnn; - u32 offset; - struct image_packet_t img_pkt; - struct tramp_img_dup_relo *relo_chain; - - /* PAYLOAD OF IMG PKT FOLLOWS */ -}; - -struct tramp_sym { - struct tramp_sym *next; /* MUST BE FIRST */ - u32 index; - u32 str_index; - struct local_symbol sym_info; -}; - -struct tramp_string { - struct tramp_string *next; /* MUST BE FIRST */ - u32 index; - char str[VARIABLE_SIZE]; /* NULL terminated */ -}; - -struct tramp_info { - u32 tramp_sect_next_addr; - struct ldr_section_info sect_info; - - struct tramp_sym *symbol_head; - struct tramp_sym *symbol_tail; - u32 tramp_sym_next_index; - struct local_symbol *final_sym_table; - - struct tramp_string *string_head; - struct tramp_string *string_tail; - u32 tramp_string_next_index; - u32 tramp_string_size; - char *final_string_table; - - struct tramp_img_pkt *tramp_pkts; - struct tramp_img_dup_pkt *dup_pkts; -}; - -/* - * States of the .cinit state machine - */ -enum cinit_mode { - CI_COUNT = 0, /* expecting a count */ - CI_ADDRESS, /* expecting an address */ -#if CINIT_ALIGN < CINIT_ADDRESS /* handle case of partial address field */ - CI_PARTADDRESS, /* have only part of the address */ -#endif - CI_COPY, /* in the middle of copying data */ - CI_DONE /* end of .cinit table */ -}; - -/* - * The internal state of the dynamic loader, which is passed around as - * an object - */ -struct dload_state { - struct dynamic_loader_stream *strm; /* The module input stream */ - struct dynamic_loader_sym *mysym; /* Symbols for this session */ - /* target memory allocator */ - struct dynamic_loader_allocate *myalloc; - struct dynamic_loader_initialize *myio; /* target memory initializer */ - unsigned myoptions; /* Options parameter dynamic_load_module */ - - char *str_head; /* Pointer to string table */ -#if BITS_PER_AU > BITS_PER_BYTE - char *str_temp; /* Pointer to temporary buffer for strings */ - /* big enough to hold longest string */ - unsigned temp_len; /* length of last temporary string */ - char *xstrings; /* Pointer to buffer for expanded */ - /* strings for sec names */ -#endif - /* Total size of strings for DLLView section names */ - unsigned debug_string_size; - /* Pointer to parallel section info for allocated sections only */ - struct doff_scnhdr_t *sect_hdrs; /* Pointer to section table */ - struct ldr_section_info *ldr_sections; -#if TMS32060 - /* The address of the start of the .bss section */ - ldr_addr bss_run_base; -#endif - struct local_symbol *local_symtab; /* Relocation symbol table */ - - /* pointer to DL section info for the section being relocated */ - struct ldr_section_info *image_secn; - /* change in run address for current section during relocation */ - ldr_addr delta_runaddr; - ldr_addr image_offset; /* offset of current packet in section */ - enum cinit_mode cinit_state; /* current state of cload_cinit() */ - int cinit_count; /* the current count */ - ldr_addr cinit_addr; /* the current address */ - s16 cinit_page; /* the current page */ - /* Handle to be returned by dynamic_load_module */ - struct my_handle *myhandle; - unsigned dload_errcount; /* Total # of errors reported so far */ - /* Number of target sections that require allocation and relocation */ - unsigned allocated_secn_count; -#ifndef TARGET_ENDIANNESS - int big_e_target; /* Target data in big-endian format */ -#endif - /* map for reordering bytes, 0 if not needed */ - u32 reorder_map; - struct doff_filehdr_t dfile_hdr; /* DOFF file header structure */ - struct doff_verify_rec_t verify; /* Verify record */ - - struct tramp_info tramp; /* Trampoline data, if needed */ - - int relstkidx; /* index into relocation value stack */ - /* relocation value stack used in relexp.c */ - rvalue relstk[STATIC_EXPR_STK_SIZE]; - -}; - -#ifdef TARGET_ENDIANNESS -#define TARGET_BIG_ENDIAN TARGET_ENDIANNESS -#else -#define TARGET_BIG_ENDIAN (dlthis->big_e_target) -#endif - -/* - * Exports from cload.c to rest of the world - */ -extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...); -extern void dload_syms_error(struct dynamic_loader_sym *syms, - const char *errtxt, ...); -extern void dload_headers(struct dload_state *dlthis); -extern void dload_strings(struct dload_state *dlthis, bool sec_names_only); -extern void dload_sections(struct dload_state *dlthis); -extern void dload_reorder(void *data, int dsiz, u32 map); -extern u32 dload_checksum(void *data, unsigned siz); - -#if HOST_ENDIANNESS -extern uint32_t dload_reverse_checksum(void *data, unsigned siz); -#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32) -extern uint32_t dload_reverse_checksum16(void *data, unsigned siz); -#endif -#endif - -/* - * exported by reloc.c - */ -extern void dload_relocate(struct dload_state *dlthis, tgt_au_t *data, - struct reloc_record_t *rp, bool *tramps_generated, - bool second_pass); - -extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data, - int fieldsz, int offset, unsigned sgn); - -extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data, - int fieldsz, int offset, unsigned sgn); - -/* - * exported by tramp.c - */ -extern bool dload_tramp_avail(struct dload_state *dlthis, - struct reloc_record_t *rp); - -int dload_tramp_generate(struct dload_state *dlthis, s16 secnn, - u32 image_offset, struct image_packet_t *ipacket, - struct reloc_record_t *rp); - -extern int dload_tramp_pkt_udpate(struct dload_state *dlthis, - s16 secnn, u32 image_offset, - struct image_packet_t *ipacket); - -extern int dload_tramp_finalize(struct dload_state *dlthis); - -extern void dload_tramp_cleanup(struct dload_state *dlthis); - -#endif /* _DLOAD_INTERNAL_ */ diff --git a/drivers/staging/tidspbridge/dynload/doff.h b/drivers/staging/tidspbridge/dynload/doff.h deleted file mode 100644 index a7c3145746ee..000000000000 --- a/drivers/staging/tidspbridge/dynload/doff.h +++ /dev/null @@ -1,354 +0,0 @@ -/* - * doff.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Structures & definitions used for dynamically loaded modules file format. - * This format is a reformatted version of COFF. It optimizes the layout for - * the dynamic loader. - * - * .dof files, when viewed as a sequence of 32-bit integers, look the same - * on big-endian and little-endian machines. - * - * 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. - */ - -#ifndef _DOFF_H -#define _DOFF_H - - -#define BYTE_RESHUFFLE_VALUE 0x00010203 - -/* DOFF file header containing fields categorizing the remainder of the file */ -struct doff_filehdr_t { - - /* string table size, including filename, in bytes */ - u32 df_strtab_size; - - /* entry point if one exists */ - u32 df_entrypt; - - /* identifies byte ordering of file; - * always set to BYTE_RESHUFFLE_VALUE */ - u32 df_byte_reshuffle; - - /* Size of the string table up to and including the last section name */ - /* Size includes the name of the COFF file also */ - u32 df_scn_name_size; - -#ifndef _BIG_ENDIAN - /* number of symbols */ - u16 df_no_syms; - - /* length in bytes of the longest string, including terminating NULL */ - /* excludes the name of the file */ - u16 df_max_str_len; - - /* total number of sections including no-load ones */ - u16 df_no_scns; - - /* number of sections containing target code allocated or downloaded */ - u16 df_target_scns; - - /* unique id for dll file format & version */ - u16 df_doff_version; - - /* identifies ISA */ - u16 df_target_id; - - /* useful file flags */ - u16 df_flags; - - /* section reference for entry point, N_UNDEF for none, */ - /* N_ABS for absolute address */ - s16 df_entry_secn; -#else - /* length of the longest string, including terminating NULL */ - u16 df_max_str_len; - - /* number of symbols */ - u16 df_no_syms; - - /* number of sections containing target code allocated or downloaded */ - u16 df_target_scns; - - /* total number of sections including no-load ones */ - u16 df_no_scns; - - /* identifies ISA */ - u16 df_target_id; - - /* unique id for dll file format & version */ - u16 df_doff_version; - - /* section reference for entry point, N_UNDEF for none, */ - /* N_ABS for absolute address */ - s16 df_entry_secn; - - /* useful file flags */ - u16 df_flags; -#endif - /* checksum for file header record */ - u32 df_checksum; - -}; - -/* flags in the df_flags field */ -#define DF_LITTLE 0x100 -#define DF_BIG 0x200 -#define DF_BYTE_ORDER (DF_LITTLE | DF_BIG) - -/* Supported processors */ -#define TMS470_ID 0x97 -#define LEAD_ID 0x98 -#define TMS32060_ID 0x99 -#define LEAD3_ID 0x9c - -/* Primary processor for loading */ -#if TMS32060 -#define TARGET_ID TMS32060_ID -#endif - -/* Verification record containing values used to test integrity of the bits */ -struct doff_verify_rec_t { - - /* time and date stamp */ - u32 dv_timdat; - - /* checksum for all section records */ - u32 dv_scn_rec_checksum; - - /* checksum for string table */ - u32 dv_str_tab_checksum; - - /* checksum for symbol table */ - u32 dv_sym_tab_checksum; - - /* checksum for verification record */ - u32 dv_verify_rec_checksum; - -}; - -/* String table is an array of null-terminated strings. The first entry is - * the filename, which is added by DLLcreate. No new structure definitions - * are required. - */ - -/* Section Records including information on the corresponding image packets */ -/* - * !!WARNING!! - * - * This structure is expected to match in form ldr_section_info in - * dynamic_loader.h - */ - -struct doff_scnhdr_t { - - s32 ds_offset; /* offset into string table of name */ - s32 ds_paddr; /* RUN address, in target AU */ - s32 ds_vaddr; /* LOAD address, in target AU */ - s32 ds_size; /* section size, in target AU */ -#ifndef _BIG_ENDIAN - u16 ds_page; /* memory page id */ - u16 ds_flags; /* section flags */ -#else - u16 ds_flags; /* section flags */ - u16 ds_page; /* memory page id */ -#endif - u32 ds_first_pkt_offset; - /* Absolute byte offset into the file */ - /* where the first image record resides */ - - s32 ds_nipacks; /* number of image packets */ - -}; - -/* Symbol table entry */ -struct doff_syment_t { - - s32 dn_offset; /* offset into string table of name */ - s32 dn_value; /* value of symbol */ -#ifndef _BIG_ENDIAN - s16 dn_scnum; /* section number */ - s16 dn_sclass; /* storage class */ -#else - s16 dn_sclass; /* storage class */ - s16 dn_scnum; /* section number, 1-based */ -#endif - -}; - -/* special values for dn_scnum */ -#define DN_UNDEF 0 /* undefined symbol */ -#define DN_ABS (-1) /* value of symbol is absolute */ -/* special values for dn_sclass */ -#define DN_EXT 2 -#define DN_STATLAB 20 -#define DN_EXTLAB 21 - -/* Default value of image bits in packet */ -/* Configurable by user on the command line */ -#define IMAGE_PACKET_SIZE 1024 - -/* An image packet contains a chunk of data from a section along with */ -/* information necessary for its processing. */ -struct image_packet_t { - - s32 num_relocs; /* number of relocations for */ - /* this packet */ - - s32 packet_size; /* number of bytes in array */ - /* "bits" occupied by */ - /* valid data. Could be */ - /* < IMAGE_PACKET_SIZE to */ - /* prevent splitting a */ - /* relocation across packets. */ - /* Last packet of a section */ - /* will most likely contain */ - /* < IMAGE_PACKET_SIZE bytes */ - /* of valid data */ - - s32 img_chksum; /* Checksum for image packet */ - /* and the corresponding */ - /* relocation records */ - - u8 *img_data; /* Actual data in section */ - -}; - -/* The relocation structure definition matches the COFF version. Offsets */ -/* however are relative to the image packet base not the section base. */ -struct reloc_record_t { - - s32 vaddr; - - /* expressed in target AUs */ - - union { - struct { -#ifndef _BIG_ENDIAN - u8 _offset; /* bit offset of rel fld */ - u8 _fieldsz; /* size of rel fld */ - u8 _wordsz; /* # bytes containing rel fld */ - u8 _dum1; - u16 _dum2; - u16 _type; -#else - unsigned _dum1:8; - unsigned _wordsz:8; /* # bytes containing rel fld */ - unsigned _fieldsz:8; /* size of rel fld */ - unsigned _offset:8; /* bit offset of rel fld */ - u16 _type; - u16 _dum2; -#endif - } _r_field; - - struct { - u32 _spc; /* image packet relative PC */ -#ifndef _BIG_ENDIAN - u16 _dum; - u16 _type; /* relocation type */ -#else - u16 _type; /* relocation type */ - u16 _dum; -#endif - } _r_spc; - - struct { - u32 _uval; /* constant value */ -#ifndef _BIG_ENDIAN - u16 _dum; - u16 _type; /* relocation type */ -#else - u16 _type; /* relocation type */ - u16 _dum; -#endif - } _r_uval; - - struct { - s32 _symndx; /* 32-bit sym tbl index */ -#ifndef _BIG_ENDIAN - u16 _disp; /* extra addr encode data */ - u16 _type; /* relocation type */ -#else - u16 _type; /* relocation type */ - u16 _disp; /* extra addr encode data */ -#endif - } _r_sym; - } _u_reloc; - -}; - -/* abbreviations for convenience */ -#ifndef TYPE -#define TYPE _u_reloc._r_sym._type -#define UVAL _u_reloc._r_uval._uval -#define SYMNDX _u_reloc._r_sym._symndx -#define OFFSET _u_reloc._r_field._offset -#define FIELDSZ _u_reloc._r_field._fieldsz -#define WORDSZ _u_reloc._r_field._wordsz -#define R_DISP _u_reloc._r_sym._disp -#endif - -/**************************************************************************** */ -/* */ -/* Important DOFF macros used for file processing */ -/* */ -/**************************************************************************** */ - -/* DOFF Versions */ -#define DOFF0 0 - -/* Return the address/size >= to addr that is at a 32-bit boundary */ -/* This assumes that a byte is 8 bits */ -#define DOFF_ALIGN(addr) (((addr) + 3) & ~3UL) - -/**************************************************************************** */ -/* */ -/* The DOFF section header flags field is laid out as follows: */ -/* */ -/* Bits 0-3 : Section Type */ -/* Bit 4 : Set when section requires target memory to be allocated by DL */ -/* Bit 5 : Set when section requires downloading */ -/* Bits 8-11: Alignment, same as COFF */ -/* */ -/**************************************************************************** */ - -/* Enum for DOFF section types (bits 0-3 of flag): See dynamic_loader.h */ -#define DS_SECTION_TYPE_MASK 0xF -/* DS_ALLOCATE indicates whether a section needs space on the target */ -#define DS_ALLOCATE_MASK 0x10 -/* DS_DOWNLOAD indicates that the loader needs to copy bits */ -#define DS_DOWNLOAD_MASK 0x20 -/* Section alignment requirement in AUs */ -#define DS_ALIGNMENT_SHIFT 8 - -static inline bool dload_check_type(struct doff_scnhdr_t *sptr, u32 flag) -{ - return (sptr->ds_flags & DS_SECTION_TYPE_MASK) == flag; -} -static inline bool ds_needs_allocation(struct doff_scnhdr_t *sptr) -{ - return sptr->ds_flags & DS_ALLOCATE_MASK; -} - -static inline bool ds_needs_download(struct doff_scnhdr_t *sptr) -{ - return sptr->ds_flags & DS_DOWNLOAD_MASK; -} - -static inline int ds_alignment(u16 ds_flags) -{ - return 1 << ((ds_flags >> DS_ALIGNMENT_SHIFT) & DS_SECTION_TYPE_MASK); -} - - -#endif /* _DOFF_H */ diff --git a/drivers/staging/tidspbridge/dynload/getsection.c b/drivers/staging/tidspbridge/dynload/getsection.c deleted file mode 100644 index e0b37714dd65..000000000000 --- a/drivers/staging/tidspbridge/dynload/getsection.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * getsection.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 <dspbridge/getsection.h> -#include "header.h" - -/* - * Error strings - */ -static const char readstrm[] = { "Error reading %s from input stream" }; -static const char seek[] = { "Set file position to %d failed" }; -static const char isiz[] = { "Bad image packet size %d" }; -static const char err_checksum[] = { "Checksum failed on %s" }; - -static const char err_reloc[] = { "dload_get_section unable to read" - "sections containing relocation entries" -}; - -#if BITS_PER_AU > BITS_PER_BYTE -static const char err_alloc[] = { "Syms->dload_allocate( %d ) failed" }; -static const char stbl[] = { "Bad string table offset " FMT_UI32 }; -#endif - -/************************************************************** */ -/********************* SUPPORT FUNCTIONS ********************** */ -/************************************************************** */ - -#if BITS_PER_AU > BITS_PER_BYTE -/************************************************************************** - * Procedure unpack_sec_name - * - * Parameters: - * dlthis Handle from dload_module_open for this module - * soffset Byte offset into the string table - * dst Place to store the expanded string - * - * Effect: - * Stores a string from the string table into the destination, expanding - * it in the process. Returns a pointer just past the end of the stored - * string on success, or NULL on failure. - * - ************************************************************************ */ -static char *unpack_sec_name(struct dload_state *dlthis, u32 soffset, char *dst) -{ - u8 tmp, *src; - - if (soffset >= dlthis->dfile_hdr.df_scn_name_size) { - dload_error(dlthis, stbl, soffset); - return NULL; - } - src = (u8 *) dlthis->str_head + - (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)); - if (soffset & 1) - *dst++ = *src++; /* only 1 character in first word */ - do { - tmp = *src++; - *dst = (tmp >> BITS_PER_BYTE) - if (!(*dst++)) - break; - } while ((*dst++ = tmp & BYTE_MASK)); - - return dst; -} - -/************************************************************************** - * Procedure expand_sec_names - * - * Parameters: - * dlthis Handle from dload_module_open for this module - * - * Effect: - * Allocates a buffer, unpacks and copies strings from string table into it. - * Stores a pointer to the buffer into a state variable. - ************************************************************************* */ -static void expand_sec_names(struct dload_state *dlthis) -{ - char *xstrings, *curr, *next; - u32 xsize; - u16 sec; - struct ldr_section_info *shp; - /* assume worst-case size requirement */ - xsize = dlthis->dfile_hdr.df_max_str_len * dlthis->dfile_hdr.df_no_scns; - xstrings = (char *)dlthis->mysym->dload_allocate(dlthis->mysym, xsize); - if (xstrings == NULL) { - dload_error(dlthis, err_alloc, xsize); - return; - } - dlthis->xstrings = xstrings; - /* For each sec, copy and expand its name */ - curr = xstrings; - for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { - shp = (struct ldr_section_info *)&dlthis->sect_hdrs[sec]; - next = unpack_sec_name(dlthis, *(u32 *) &shp->name, curr); - if (next == NULL) - break; /* error */ - shp->name = curr; - curr = next; - } -} - -#endif - -/************************************************************** */ -/********************* EXPORTED FUNCTIONS ********************* */ -/************************************************************** */ - -/************************************************************************** - * Procedure dload_module_open - * - * Parameters: - * module The input stream that supplies the module image - * syms Host-side malloc/free and error reporting functions. - * Other methods are unused. - * - * Effect: - * Reads header information from a dynamic loader module using the - specified - * stream object, and returns a handle for the module information. This - * handle may be used in subsequent query calls to obtain information - * contained in the module. - * - * Returns: - * NULL if an error is encountered, otherwise a module handle for use - * in subsequent operations. - ************************************************************************* */ -void *dload_module_open(struct dynamic_loader_stream *module, - struct dynamic_loader_sym *syms) -{ - struct dload_state *dlthis; /* internal state for this call */ - unsigned *dp, sz; - u32 sec_start; -#if BITS_PER_AU <= BITS_PER_BYTE - u16 sec; -#endif - - /* Check that mandatory arguments are present */ - if (!module || !syms) { - if (syms != NULL) - dload_syms_error(syms, "Required parameter is NULL"); - - return NULL; - } - - dlthis = (struct dload_state *) - syms->dload_allocate(syms, sizeof(struct dload_state)); - if (!dlthis) { - /* not enough storage */ - dload_syms_error(syms, "Can't allocate module info"); - return NULL; - } - - /* clear our internal state */ - dp = (unsigned *)dlthis; - for (sz = sizeof(struct dload_state) / sizeof(unsigned); - sz > 0; sz -= 1) - *dp++ = 0; - - dlthis->strm = module; - dlthis->mysym = syms; - - /* read in the doff image and store in our state variable */ - dload_headers(dlthis); - - if (!dlthis->dload_errcount) - dload_strings(dlthis, true); - - /* skip ahead past the unread portion of the string table */ - sec_start = sizeof(struct doff_filehdr_t) + - sizeof(struct doff_verify_rec_t) + - BYTE_TO_HOST(DOFF_ALIGN(dlthis->dfile_hdr.df_strtab_size)); - - if (dlthis->strm->set_file_posn(dlthis->strm, sec_start) != 0) { - dload_error(dlthis, seek, sec_start); - return NULL; - } - - if (!dlthis->dload_errcount) - dload_sections(dlthis); - - if (dlthis->dload_errcount) { - dload_module_close(dlthis); /* errors, blow off our state */ - dlthis = NULL; - return NULL; - } -#if BITS_PER_AU > BITS_PER_BYTE - /* Expand all section names from the string table into the */ - /* state variable, and convert section names from a relative */ - /* string table offset to a pointers to the expanded string. */ - expand_sec_names(dlthis); -#else - /* Convert section names from a relative string table offset */ - /* to a pointer into the string table. */ - for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { - struct ldr_section_info *shp = - (struct ldr_section_info *)&dlthis->sect_hdrs[sec]; - shp->name = dlthis->str_head + *(u32 *) &shp->name; - } -#endif - - return dlthis; -} - -/*************************************************************************** - * Procedure dload_get_section_info - * - * Parameters: - * minfo Handle from dload_module_open for this module - * section_name Pointer to the string name of the section desired - * section_info Address of a section info structure pointer to be - * initialized - * - * Effect: - * Finds the specified section in the module information, and initializes - * the provided struct ldr_section_info pointer. - * - * Returns: - * true for success, false for section not found - ************************************************************************* */ -int dload_get_section_info(void *minfo, const char *section_name, - const struct ldr_section_info **const section_info) -{ - struct dload_state *dlthis; - struct ldr_section_info *shp; - u16 sec; - - dlthis = (struct dload_state *)minfo; - if (!dlthis) - return false; - - for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) { - shp = (struct ldr_section_info *)&dlthis->sect_hdrs[sec]; - if (strcmp(section_name, shp->name) == 0) { - *section_info = shp; - return true; - } - } - - return false; -} - -#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32)) - -/************************************************************************** - * Procedure dload_get_section - * - * Parameters: - * minfo Handle from dload_module_open for this module - * section_info Pointer to a section info structure for the desired - * section - * section_data Buffer to contain the section initialized data - * - * Effect: - * Copies the initialized data for the specified section into the - * supplied buffer. - * - * Returns: - * true for success, false for section not found - ************************************************************************* */ -int dload_get_section(void *minfo, - const struct ldr_section_info *section_info, - void *section_data) -{ - struct dload_state *dlthis; - u32 pos; - struct doff_scnhdr_t *sptr = NULL; - s32 nip; - struct image_packet_t ipacket; - s32 ipsize; - u32 checks; - s8 *dest = (s8 *) section_data; - - dlthis = (struct dload_state *)minfo; - if (!dlthis) - return false; - sptr = (struct doff_scnhdr_t *)section_info; - if (sptr == NULL) - return false; - - /* skip ahead to the start of the first packet */ - pos = BYTE_TO_HOST(DOFF_ALIGN((u32) sptr->ds_first_pkt_offset)); - if (dlthis->strm->set_file_posn(dlthis->strm, pos) != 0) { - dload_error(dlthis, seek, pos); - return false; - } - - nip = sptr->ds_nipacks; - while ((nip -= 1) >= 0) { /* for each packet */ - /* get the fixed header bits */ - if (dlthis->strm->read_buffer(dlthis->strm, &ipacket, - IPH_SIZE) != IPH_SIZE) { - dload_error(dlthis, readstrm, "image packet"); - return false; - } - /* reorder the header if need be */ - if (dlthis->reorder_map) - dload_reorder(&ipacket, IPH_SIZE, dlthis->reorder_map); - - /* Now read the packet image bits. Note: round the size up to - * the next multiple of 4 bytes; this is what checksum - * routines want. */ - ipsize = BYTE_TO_HOST(DOFF_ALIGN(ipacket.packet_size)); - if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) { - dload_error(dlthis, isiz, ipsize); - return false; - } - if (dlthis->strm->read_buffer - (dlthis->strm, dest, ipsize) != ipsize) { - dload_error(dlthis, readstrm, "image packet"); - return false; - } - /* reorder the bytes if need be */ -#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16) - if (dlthis->reorder_map) - dload_reorder(dest, ipsize, dlthis->reorder_map); - - checks = dload_checksum(dest, ipsize); -#else - if (dlthis->dfile_hdr.df_byte_reshuffle != - TARGET_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) { - /* put image bytes in big-endian order, not PC order */ - dload_reorder(dest, ipsize, - TARGET_ORDER(dlthis-> - dfile_hdr.df_byte_reshuffle)); - } -#if TARGET_AU_BITS > 8 - checks = dload_reverse_checksum16(dest, ipsize); -#else - checks = dload_reverse_checksum(dest, ipsize); -#endif -#endif - checks += dload_checksum(&ipacket, IPH_SIZE); - - /* NYI: unable to handle relocation entries here. Reloc - * entries referring to fields that span the packet boundaries - * may result in packets of sizes that are not multiple of - * 4 bytes. Our checksum implementation works on 32-bit words - * only. */ - if (ipacket.num_relocs != 0) { - dload_error(dlthis, err_reloc, ipsize); - return false; - } - - if (~checks) { - dload_error(dlthis, err_checksum, "image packet"); - return false; - } - - /*Advance destination ptr by the size of the just-read packet */ - dest += ipsize; - } - - return true; -} - -/*************************************************************************** - * Procedure dload_module_close - * - * Parameters: - * minfo Handle from dload_module_open for this module - * - * Effect: - * Releases any storage associated with the module handle. On return, - * the module handle is invalid. - * - * Returns: - * Zero for success. On error, the number of errors detected is returned. - * Individual errors are reported using syms->error_report(), where syms was - * an argument to dload_module_open - ************************************************************************* */ -void dload_module_close(void *minfo) -{ - struct dload_state *dlthis; - - dlthis = (struct dload_state *)minfo; - if (!dlthis) - return; - - if (dlthis->str_head) - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->str_head); - - if (dlthis->sect_hdrs) - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->sect_hdrs); - -#if BITS_PER_AU > BITS_PER_BYTE - if (dlthis->xstrings) - dlthis->mysym->dload_deallocate(dlthis->mysym, - dlthis->xstrings); - -#endif - - dlthis->mysym->dload_deallocate(dlthis->mysym, dlthis); -} diff --git a/drivers/staging/tidspbridge/dynload/header.h b/drivers/staging/tidspbridge/dynload/header.h deleted file mode 100644 index 5b50a15a343e..000000000000 --- a/drivers/staging/tidspbridge/dynload/header.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * header.h - * - * 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/string.h> -#define DL_STRCMP strcmp - -/* maximum parenthesis nesting in relocation stack expressions */ -#define STATIC_EXPR_STK_SIZE 10 - -#include <linux/types.h> - -#include "doff.h" -#include <dspbridge/dynamic_loader.h> -#include "params.h" -#include "dload_internal.h" -#include "reloc_table.h" - -/* - * Plausibility limits - * - * These limits are imposed upon the input DOFF file as a check for validity. - * They are hard limits, in that the load will fail if they are exceeded. - * The numbers selected are arbitrary, in that the loader implementation does - * not require these limits. - */ - -/* maximum number of bytes in string table */ -#define MAX_REASONABLE_STRINGTAB (0x100000) -/* maximum number of code,data,etc. sections */ -#define MAX_REASONABLE_SECTIONS (200) -/* maximum number of linker symbols */ -#define MAX_REASONABLE_SYMBOLS (100000) - -/* shift count to align F_BIG with DLOAD_LITTLE */ -#define ALIGN_COFF_ENDIANNESS 7 -#define ENDIANNESS_MASK (DF_BYTE_ORDER >> ALIGN_COFF_ENDIANNESS) diff --git a/drivers/staging/tidspbridge/dynload/module_list.h b/drivers/staging/tidspbridge/dynload/module_list.h deleted file mode 100644 index a216bb131a40..000000000000 --- a/drivers/staging/tidspbridge/dynload/module_list.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * dspbridge/mpu_driver/src/dynload/module_list.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2008 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. - */ - -/* - * This C header file gives the layout of the data structure created by the - * dynamic loader to describe the set of modules loaded into the DSP. - * - * Linked List Structure: - * ---------------------- - * The data structure defined here is a singly-linked list. The list - * represents the set of modules which are currently loaded in the DSP memory. - * The first entry in the list is a header record which contains a flag - * representing the state of the list. The rest of the entries in the list - * are module records. - * - * Global symbol _DLModules designates the first record in the list (i.e. the - * header record). This symbol must be defined in any program that wishes to - * use DLLview plug-in. - * - * String Representation: - * ---------------------- - * The string names of the module and its sections are stored in a block of - * memory which follows the module record itself. The strings are ordered: - * module name first, followed by section names in order from the first - * section to the last. String names are tightly packed arrays of 8-bit - * characters (two characters per 16-bit word on the C55x). Strings are - * zero-byte-terminated. - * - * Creating and updating the list: - * ------------------------------- - * Upon loading a new module into the DSP memory the dynamic loader inserts a - * new module record as the first module record in the list. The fields of - * this module record are initialized to reflect the properties of the module. - * The dynamic loader does NOT increment the flag/counter in the list's header - * record. - * - * Upon unloading a module from the DSP memory the dynamic loader removes the - * module's record from this list. The dynamic loader also increments the - * flag/counter in the list's header record to indicate that the list has been - * changed. - */ - -#ifndef _MODULE_LIST_H_ -#define _MODULE_LIST_H_ - -#include <linux/types.h> - -/* Global pointer to the modules_header structure */ -#define MODULES_HEADER "_DLModules" -#define MODULES_HEADER_NO_UNDERSCORE "DLModules" - -/* Initial version number */ -#define INIT_VERSION 1 - -/* Verification number -- to be recorded in each module record */ -#define VERIFICATION 0x79 - -/* forward declarations */ -struct dll_module; -struct dll_sect; - -/* the first entry in the list is the modules_header record; - * its address is contained in the global _DLModules pointer */ -struct modules_header { - - /* - * Address of the first dll_module record in the list or NULL. - * Note: for C55x this is a word address (C55x data is - * word-addressable) - */ - u32 first_module; - - /* Combined storage size (in target addressable units) of the - * dll_module record which follows this header record, or zero - * if the list is empty. This size includes the module's string table. - * Note: for C55x the unit is a 16-bit word */ - u16 first_module_size; - - /* Counter is incremented whenever a module record is removed from - * the list */ - u16 update_flag; - -}; - -/* for each 32-bits in above structure, a bitmap, LSB first, whose bits are: - * 0 => a 32-bit value, 1 => 2 16-bit values */ -/* swapping bitmap for type modules_header */ -#define MODULES_HEADER_BITMAP 0x2 - -/* information recorded about each section in a module */ -struct dll_sect { - - /* Load-time address of the section. - * Note: for C55x this is a byte address for program sections, and - * a word address for data sections. C55x program memory is - * byte-addressable, while data memory is word-addressable. */ - u32 sect_load_adr; - - /* Run-time address of the section. - * Note 1: for C55x this is a byte address for program sections, and - * a word address for data sections. - * Note 2: for C55x two most significant bits of this field indicate - * the section type: '00' for a code section, '11' for a data section - * (C55 addresses are really only 24-bits wide). */ - u32 sect_run_adr; - -}; - -/* the rest of the entries in the list are module records */ -struct dll_module { - - /* Address of the next dll_module record in the list, or 0 if this is - * the last record in the list. - * Note: for C55x this is a word address (C55x data is - * word-addressable) */ - u32 next_module; - - /* Combined storage size (in target addressable units) of the - * dll_module record which follows this one, or zero if this is the - * last record in the list. This size includes the module's string - * table. - * Note: for C55x the unit is a 16-bit word. */ - u16 next_module_size; - - /* version number of the tooling; set to INIT_VERSION for Phase 1 */ - u16 version; - - /* the verification word; set to VERIFICATION */ - u16 verification; - - /* Number of sections in the sects array */ - u16 num_sects; - - /* Module's "unique" id; copy of the timestamp from the host - * COFF file */ - u32 timestamp; - - /* Array of num_sects elements of the module's section records */ - struct dll_sect sects[1]; -}; - -/* for each 32 bits in above structure, a bitmap, LSB first, whose bits are: - * 0 => a 32-bit value, 1 => 2 16-bit values */ -#define DLL_MODULE_BITMAP 0x6 /* swapping bitmap for type dll_module */ - -#endif /* _MODULE_LIST_H_ */ diff --git a/drivers/staging/tidspbridge/dynload/params.h b/drivers/staging/tidspbridge/dynload/params.h deleted file mode 100644 index d797fcd3b662..000000000000 --- a/drivers/staging/tidspbridge/dynload/params.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * params.h - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * This file defines host and target properties for all machines - * supported by the dynamic loader. To be tedious... - * - * host: the machine on which the dynamic loader runs - * target: the machine that the dynamic loader is loading - * - * Host and target may or may not be the same, depending upon the particular - * use. - * - * 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. - */ - -/****************************************************************************** - * - * Host Properties - * - **************************************************************************** */ - -#define BITS_PER_BYTE 8 /* bits in the standard PC/SUN byte */ -#define LOG_BITS_PER_BYTE 3 /* log base 2 of same */ -#define BYTE_MASK ((1U<<BITS_PER_BYTE)-1) - -#if defined(__TMS320C55X__) || defined(_TMS320C5XX) -#define BITS_PER_AU 16 -#define LOG_BITS_PER_AU 4 - /* use this print string in error messages for uint32_t */ -#define FMT_UI32 "0x%lx" -#define FMT8_UI32 "%08lx" /* same but no 0x, fixed width field */ -#else -/* bits in the smallest addressable data storage unit */ -#define BITS_PER_AU 8 -/* log base 2 of the same; useful for shift counts */ -#define LOG_BITS_PER_AU 3 -#define FMT_UI32 "0x%x" -#define FMT8_UI32 "%08x" -#endif - -/* generic fastest method for swapping bytes and shorts */ -#define SWAP32BY16(zz) (((zz) << 16) | ((zz) >> 16)) -#define SWAP16BY8(zz) (((zz) << 8) | ((zz) >> 8)) - -/* !! don't be tempted to insert type definitions here; use <stdint.h> !! */ - -/****************************************************************************** - * - * Target Properties - * - **************************************************************************** */ - -/*-------------------------------------------------------------------------- */ -/* TMS320C6x Target Specific Parameters (byte-addressable) */ -/*-------------------------------------------------------------------------- */ -#if TMS32060 -#define MEMORG 0x0L /* Size of configured memory */ -#define MEMSIZE 0x0L /* (full address space) */ - -#define CINIT_ALIGN 8 /* alignment of cinit record in TDATA AUs */ -#define CINIT_COUNT 4 /* width of count field in TDATA AUs */ -#define CINIT_ADDRESS 4 /* width of address field in TDATA AUs */ -#define CINIT_PAGE_BITS 0 /* Number of LSBs of address that - * are page number */ - -#define LENIENT_SIGNED_RELEXPS 0 /* DOES SIGNED ALLOW MAX UNSIGNED */ - -#undef TARGET_ENDIANNESS /* may be big or little endian */ - -/* align a target address to a word boundary */ -#define TARGET_WORD_ALIGN(zz) (((zz) + 0x3) & -0x4) -#endif - -/*-------------------------------------------------------------------------- - * - * DEFAULT SETTINGS and DERIVED PROPERTIES - * - * This section establishes defaults for values not specified above - *-------------------------------------------------------------------------- */ -#ifndef TARGET_AU_BITS -#define TARGET_AU_BITS 8 /* width of the target addressable unit */ -#define LOG_TARGET_AU_BITS 3 /* log2 of same */ -#endif - -#ifndef CINIT_DEFAULT_PAGE -#define CINIT_DEFAULT_PAGE 0 /* default .cinit page number */ -#endif - -#ifndef DATA_RUN2LOAD -#define DATA_RUN2LOAD(zz) (zz) /* translate data run address to load address */ -#endif - -#ifndef DBG_LIST_PAGE -#define DBG_LIST_PAGE 0 /* page number for .dllview section */ -#endif - -#ifndef TARGET_WORD_ALIGN -/* align a target address to a word boundary */ -#define TARGET_WORD_ALIGN(zz) (zz) -#endif - -#ifndef TDATA_TO_TADDR -#define TDATA_TO_TADDR(zz) (zz) /* target data address to target AU address */ -#define TADDR_TO_TDATA(zz) (zz) /* target AU address to target data address */ -#define TDATA_AU_BITS TARGET_AU_BITS /* bits per data AU */ -#define LOG_TDATA_AU_BITS LOG_TARGET_AU_BITS -#endif - -/* - * - * Useful properties and conversions derived from the above - * - */ - -/* - * Conversions between host and target addresses - */ -#if LOG_BITS_PER_AU == LOG_TARGET_AU_BITS -/* translate target addressable unit to host address */ -#define TADDR_TO_HOST(x) (x) -/* translate host address to target addressable unit */ -#define HOST_TO_TADDR(x) (x) -#elif LOG_BITS_PER_AU > LOG_TARGET_AU_BITS -#define TADDR_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS)) -#define HOST_TO_TADDR(x) ((x) << (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS)) -#else -#define TADDR_TO_HOST(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU)) -#define HOST_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU)) -#endif - -#if LOG_BITS_PER_AU == LOG_TDATA_AU_BITS -/* translate target addressable unit to host address */ -#define TDATA_TO_HOST(x) (x) -/* translate host address to target addressable unit */ -#define HOST_TO_TDATA(x) (x) -/* translate host address to target addressable unit, round up */ -#define HOST_TO_TDATA_ROUND(x) (x) -/* byte offset to host offset, rounded up for TDATA size */ -#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x) -#elif LOG_BITS_PER_AU > LOG_TDATA_AU_BITS -#define TDATA_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) -#define HOST_TO_TDATA(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) -#define HOST_TO_TDATA_ROUND(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS)) -#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x) -#else -#define TDATA_TO_HOST(x) ((x) << (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) -#define HOST_TO_TDATA(x) ((x) >> (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) -#define HOST_TO_TDATA_ROUND(x) (((x) +\ - (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))-1) >>\ - (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU)) -#define BYTE_TO_HOST_TDATA_ROUND(x) (BYTE_TO_HOST((x) +\ - (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_BYTE))-1) &\ - -(TDATA_AU_BITS/BITS_PER_AU)) -#endif - -/* - * Input in DOFF format is always expresed in bytes, regardless of loading host - * so we wind up converting from bytes to target and host units even when the - * host is not a byte machine. - */ -#if LOG_BITS_PER_AU == LOG_BITS_PER_BYTE -#define BYTE_TO_HOST(x) (x) -#define BYTE_TO_HOST_ROUND(x) (x) -#define HOST_TO_BYTE(x) (x) -#elif LOG_BITS_PER_AU >= LOG_BITS_PER_BYTE -#define BYTE_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) -#define BYTE_TO_HOST_ROUND(x) ((x + (BITS_PER_AU/BITS_PER_BYTE-1)) >>\ - (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) -#define HOST_TO_BYTE(x) ((x) << (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE)) -#else -/* lets not try to deal with sub-8-bit byte machines */ -#endif - -#if LOG_TARGET_AU_BITS == LOG_BITS_PER_BYTE -/* translate target addressable unit to byte address */ -#define TADDR_TO_BYTE(x) (x) -/* translate byte address to target addressable unit */ -#define BYTE_TO_TADDR(x) (x) -#elif LOG_TARGET_AU_BITS > LOG_BITS_PER_BYTE -#define TADDR_TO_BYTE(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE)) -#define BYTE_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE)) -#else -/* lets not try to deal with sub-8-bit byte machines */ -#endif - -#ifdef _BIG_ENDIAN -#define HOST_ENDIANNESS 1 -#else -#define HOST_ENDIANNESS 0 -#endif - -#ifdef TARGET_ENDIANNESS -#define TARGET_ENDIANNESS_DIFFERS(rtend) (HOST_ENDIANNESS^TARGET_ENDIANNESS) -#elif HOST_ENDIANNESS -#define TARGET_ENDIANNESS_DIFFERS(rtend) (!(rtend)) -#else -#define TARGET_ENDIANNESS_DIFFERS(rtend) (rtend) -#endif - -/* the unit in which we process target image data */ -#if TARGET_AU_BITS <= 8 -typedef u8 tgt_au_t; -#elif TARGET_AU_BITS <= 16 -typedef u16 tgt_au_t; -#else -typedef u32 tgt_au_t; -#endif - -/* size of that unit */ -#if TARGET_AU_BITS < BITS_PER_AU -#define TGTAU_BITS BITS_PER_AU -#define LOG_TGTAU_BITS LOG_BITS_PER_AU -#else -#define TGTAU_BITS TARGET_AU_BITS -#define LOG_TGTAU_BITS LOG_TARGET_AU_BITS -#endif diff --git a/drivers/staging/tidspbridge/dynload/reloc.c b/drivers/staging/tidspbridge/dynload/reloc.c deleted file mode 100644 index 463abdb6392f..000000000000 --- a/drivers/staging/tidspbridge/dynload/reloc.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * reloc.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 "header.h" - -#if TMS32060 -/* the magic symbol for the start of BSS */ -static const char bsssymbol[] = { ".bss" }; -#endif - -#if TMS32060 -#include "reloc_table_c6000.c" -#endif - -#if TMS32060 -/* From coff.h - ignore these relocation operations */ -#define R_C60ALIGN 0x76 /* C60: Alignment info for compressor */ -#define R_C60FPHEAD 0x77 /* C60: Explicit assembly directive */ -#define R_C60NOCMP 0x100 /* C60: Don't compress this code scn */ -#endif - -/************************************************************************** - * Procedure dload_unpack - * - * Parameters: - * data pointer to storage unit containing lowest host address of - * image data - * fieldsz Size of bit field, 0 < fieldsz <= sizeof(rvalue)*BITS_PER_AU - * offset Offset from LSB, 0 <= offset < BITS_PER_AU - * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY) - * - * Effect: - * Extracts the specified field and returns it. - ************************************************************************* */ -rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t *data, int fieldsz, - int offset, unsigned sgn) -{ - register rvalue objval; - register int shift, direction; - register tgt_au_t *dp = data; - - fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value */ - /* * collect up enough bits to contain the desired field */ - if (TARGET_BIG_ENDIAN) { - dp += (fieldsz + offset) >> LOG_TGTAU_BITS; - direction = -1; - } else - direction = 1; - objval = *dp >> offset; - shift = TGTAU_BITS - offset; - while (shift <= fieldsz) { - dp += direction; - objval += (rvalue) *dp << shift; - shift += TGTAU_BITS; - } - - /* * sign or zero extend the value appropriately */ - if (sgn == ROP_UNS) - objval &= (2 << fieldsz) - 1; - else { - shift = sizeof(rvalue) * BITS_PER_AU - 1 - fieldsz; - objval = (objval << shift) >> shift; - } - - return objval; - -} /* dload_unpack */ - -/************************************************************************** - * Procedure dload_repack - * - * Parameters: - * val Value to insert - * data Pointer to storage unit containing lowest host address of - * image data - * fieldsz Size of bit field, 0 < fieldsz <= sizeof(rvalue)*BITS_PER_AU - * offset Offset from LSB, 0 <= offset < BITS_PER_AU - * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY) - * - * Effect: - * Stuffs the specified value in the specified field. Returns 0 for - * success - * or 1 if the value will not fit in the specified field according to the - * specified signedness rule. - ************************************************************************* */ -static const unsigned char ovf_limit[] = { 1, 2, 2 }; - -int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t *data, - int fieldsz, int offset, unsigned sgn) -{ - register urvalue objval, mask; - register int shift, direction; - register tgt_au_t *dp = data; - - fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value */ - /* clip the bits */ - mask = (2UL << fieldsz) - 1; - objval = (val & mask); - /* * store the bits through the specified mask */ - if (TARGET_BIG_ENDIAN) { - dp += (fieldsz + offset) >> LOG_TGTAU_BITS; - direction = -1; - } else - direction = 1; - - /* insert LSBs */ - *dp = (*dp & ~(mask << offset)) + (objval << offset); - shift = TGTAU_BITS - offset; - /* align mask and objval with AU boundary */ - objval >>= shift; - mask >>= shift; - - while (mask) { - dp += direction; - *dp = (*dp & ~mask) + objval; - objval >>= TGTAU_BITS; - mask >>= TGTAU_BITS; - } - - /* - * check for overflow - */ - if (sgn) { - unsigned tmp = (val >> fieldsz) + (sgn & 0x1); - if (tmp > ovf_limit[sgn - 1]) - return 1; - } - return 0; - -} /* dload_repack */ - -/* lookup table for the scaling amount in a C6x instruction */ -#if TMS32060 -#define SCALE_BITS 4 /* there are 4 bits in the scale field */ -#define SCALE_MASK 0x7 /* we really only use the bottom 3 bits */ -static const u8 c60_scale[SCALE_MASK + 1] = { - 1, 0, 0, 0, 1, 1, 2, 2 -}; -#endif - -/************************************************************************** - * Procedure dload_relocate - * - * Parameters: - * data Pointer to base of image data - * rp Pointer to relocation operation - * - * Effect: - * Performs the specified relocation operation - ************************************************************************* */ -void dload_relocate(struct dload_state *dlthis, tgt_au_t *data, - struct reloc_record_t *rp, bool *tramps_generated, - bool second_pass) -{ - rvalue val, reloc_amt, orig_val = 0; - unsigned int fieldsz = 0; - unsigned int offset = 0; - unsigned int reloc_info = 0; - unsigned int reloc_action = 0; - register int rx = 0; - rvalue *stackp = NULL; - int top; - struct local_symbol *svp = NULL; -#ifdef RFV_SCALE - unsigned int scale = 0; -#endif - struct image_packet_t *img_pkt = NULL; - - /* The image packet data struct is only used during first pass - * relocation in the event that a trampoline is needed. 2nd pass - * relocation doesn't guarantee that data is coming from an - * image_packet_t structure. See cload.c, dload_data for how img_data is - * set. If that changes this needs to be updated!!! */ - if (second_pass == false) - img_pkt = (struct image_packet_t *)((u8 *) data - - sizeof(struct - image_packet_t)); - - rx = HASH_FUNC(rp->TYPE); - while (rop_map1[rx] != rp->TYPE) { - rx = HASH_L(rop_map2[rx]); - if (rx < 0) { -#if TMS32060 - switch (rp->TYPE) { - case R_C60ALIGN: - case R_C60NOCMP: - case R_C60FPHEAD: - /* Ignore these reloc types and return */ - break; - default: - /* Unknown reloc type, print error and return */ - dload_error(dlthis, "Bad coff operator 0x%x", - rp->TYPE); - } -#else - dload_error(dlthis, "Bad coff operator 0x%x", rp->TYPE); -#endif - return; - } - } - rx = HASH_I(rop_map2[rx]); - if ((rx < (sizeof(rop_action) / sizeof(u16))) - && (rx < (sizeof(rop_info) / sizeof(u16))) && (rx > 0)) { - reloc_action = rop_action[rx]; - reloc_info = rop_info[rx]; - } else { - dload_error(dlthis, "Buffer Overflow - Array Index Out " - "of Bounds"); - } - - /* Compute the relocation amount for the referenced symbol, if any */ - reloc_amt = rp->UVAL; - if (RFV_SYM(reloc_info)) { /* relocation uses a symbol reference */ - /* If this is first pass, use the module local symbol table, - * else use the trampoline symbol table. */ - if (second_pass == false) { - if ((u32) rp->SYMNDX < dlthis->dfile_hdr.df_no_syms) { - /* real symbol reference */ - svp = &dlthis->local_symtab[rp->SYMNDX]; - reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ? - svp->delta : svp->value; - } - /* reloc references current section */ - else if (rp->SYMNDX == -1) { - reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ? - dlthis->delta_runaddr : - dlthis->image_secn->run_addr; - } - } - } - /* relocation uses a symbol reference */ - /* Handle stack adjustment */ - val = 0; - top = RFV_STK(reloc_info); - if (top) { - top += dlthis->relstkidx - RSTK_UOP; - if (top >= STATIC_EXPR_STK_SIZE) { - dload_error(dlthis, - "Expression stack overflow in %s at offset " - FMT_UI32, dlthis->image_secn->name, - rp->vaddr + dlthis->image_offset); - return; - } - val = dlthis->relstk[dlthis->relstkidx]; - dlthis->relstkidx = top; - stackp = &dlthis->relstk[top]; - } - /* Derive field position and size, if we need them */ - if (reloc_info & ROP_RW) { /* read or write action in our future */ - fieldsz = RFV_WIDTH(reloc_action); - if (fieldsz) { /* field info from table */ - offset = RFV_POSN(reloc_action); - if (TARGET_BIG_ENDIAN) - /* make sure vaddr is the lowest target - * address containing bits */ - rp->vaddr += RFV_BIGOFF(reloc_info); - } else { /* field info from relocation op */ - fieldsz = rp->FIELDSZ; - offset = rp->OFFSET; - if (TARGET_BIG_ENDIAN) - /* make sure vaddr is the lowest target - address containing bits */ - rp->vaddr += (rp->WORDSZ - offset - fieldsz) - >> LOG_TARGET_AU_BITS; - } - data = (tgt_au_t *) ((char *)data + TADDR_TO_HOST(rp->vaddr)); - /* compute lowest host location of referenced data */ -#if BITS_PER_AU > TARGET_AU_BITS - /* conversion from target address to host address may lose - address bits; add loss to offset */ - if (TARGET_BIG_ENDIAN) { - offset += -((rp->vaddr << LOG_TARGET_AU_BITS) + - offset + fieldsz) & - (BITS_PER_AU - TARGET_AU_BITS); - } else { - offset += (rp->vaddr << LOG_TARGET_AU_BITS) & - (BITS_PER_AU - 1); - } -#endif -#ifdef RFV_SCALE - scale = RFV_SCALE(reloc_info); -#endif - } - /* read the object value from the current image, if so ordered */ - if (reloc_info & ROP_R) { - /* relocation reads current image value */ - val = dload_unpack(dlthis, data, fieldsz, offset, - RFV_SIGN(reloc_info)); - /* Save off the original value in case the relo overflows and - * we can trampoline it. */ - orig_val = val; - -#ifdef RFV_SCALE - val <<= scale; -#endif - } - /* perform the necessary arithmetic */ - switch (RFV_ACTION(reloc_action)) { /* relocation actions */ - case RACT_VAL: - break; - case RACT_ASGN: - val = reloc_amt; - break; - case RACT_ADD: - val += reloc_amt; - break; - case RACT_PCR: - /*----------------------------------------------------------- - * Handle special cases of jumping from absolute sections - * (special reloc type) or to absolute destination - * (symndx == -1). In either case, set the appropriate - * relocation amount to 0. - *----------------------------------------------------------- */ - if (rp->SYMNDX == -1) - reloc_amt = 0; - val += reloc_amt - dlthis->delta_runaddr; - break; - case RACT_ADDISP: - val += rp->R_DISP + reloc_amt; - break; - case RACT_ASGPC: - val = dlthis->image_secn->run_addr + reloc_amt; - break; - case RACT_PLUS: - if (stackp != NULL) - val += *stackp; - break; - case RACT_SUB: - if (stackp != NULL) - val = *stackp - val; - break; - case RACT_NEG: - val = -val; - break; - case RACT_MPY: - if (stackp != NULL) - val *= *stackp; - break; - case RACT_DIV: - if (stackp != NULL) - val = *stackp / val; - break; - case RACT_MOD: - if (stackp != NULL) - val = *stackp % val; - break; - case RACT_SR: - if (val >= sizeof(rvalue) * BITS_PER_AU) - val = 0; - else if (stackp != NULL) - val = (urvalue) *stackp >> val; - break; - case RACT_ASR: - if (val >= sizeof(rvalue) * BITS_PER_AU) - val = sizeof(rvalue) * BITS_PER_AU - 1; - else if (stackp != NULL) - val = *stackp >> val; - break; - case RACT_SL: - if (val >= sizeof(rvalue) * BITS_PER_AU) - val = 0; - else if (stackp != NULL) - val = *stackp << val; - break; - case RACT_AND: - if (stackp != NULL) - val &= *stackp; - break; - case RACT_OR: - if (stackp != NULL) - val |= *stackp; - break; - case RACT_XOR: - if (stackp != NULL) - val ^= *stackp; - break; - case RACT_NOT: - val = ~val; - break; -#if TMS32060 - case RACT_C6SECT: - /* actually needed address of secn containing symbol */ - if (svp != NULL) { - if (rp->SYMNDX >= 0) - if (svp->secnn > 0) - reloc_amt = dlthis->ldr_sections - [svp->secnn - 1].run_addr; - } - /* !!! FALL THRU !!! */ - case RACT_C6BASE: - if (dlthis->bss_run_base == 0) { - struct dynload_symbol *symp; - symp = dlthis->mysym->find_matching_symbol - (dlthis->mysym, bsssymbol); - /* lookup value of global BSS base */ - if (symp) - dlthis->bss_run_base = symp->value; - else - dload_error(dlthis, - "Global BSS base referenced in %s " - "offset" FMT_UI32 " but not " - "defined", - dlthis->image_secn->name, - rp->vaddr + dlthis->image_offset); - } - reloc_amt -= dlthis->bss_run_base; - /* !!! FALL THRU !!! */ - case RACT_C6DSPL: - /* scale factor determined by 3 LSBs of field */ - scale = c60_scale[val & SCALE_MASK]; - offset += SCALE_BITS; - fieldsz -= SCALE_BITS; - val >>= SCALE_BITS; /* ignore the scale field hereafter */ - val <<= scale; - val += reloc_amt; /* do the usual relocation */ - if (((1 << scale) - 1) & val) - dload_error(dlthis, - "Unaligned reference in %s offset " - FMT_UI32, dlthis->image_secn->name, - rp->vaddr + dlthis->image_offset); - break; -#endif - } /* relocation actions */ - /* * Put back result as required */ - if (reloc_info & ROP_W) { /* relocation writes image value */ -#ifdef RFV_SCALE - val >>= scale; -#endif - if (dload_repack(dlthis, val, data, fieldsz, offset, - RFV_SIGN(reloc_info))) { - /* Check to see if this relo can be trampolined, - * but only in first phase relocation. 2nd phase - * relocation cannot trampoline. */ - if ((second_pass == false) && - (dload_tramp_avail(dlthis, rp) == true)) { - - /* Before generating the trampoline, restore - * the value to its original so the 2nd pass - * relo will work. */ - dload_repack(dlthis, orig_val, data, fieldsz, - offset, RFV_SIGN(reloc_info)); - if (!dload_tramp_generate(dlthis, - (dlthis->image_secn - - dlthis->ldr_sections), - dlthis->image_offset, - img_pkt, rp)) { - dload_error(dlthis, - "Failed to " - "generate trampoline for " - "bit overflow"); - dload_error(dlthis, - "Relocation val " FMT_UI32 - " overflows %d bits in %s " - "offset " FMT_UI32, val, - fieldsz, - dlthis->image_secn->name, - dlthis->image_offset + - rp->vaddr); - } else - *tramps_generated = true; - } else { - dload_error(dlthis, "Relocation value " - FMT_UI32 " overflows %d bits in %s" - " offset " FMT_UI32, val, fieldsz, - dlthis->image_secn->name, - dlthis->image_offset + rp->vaddr); - } - } - } else if (top) - *stackp = val; -} /* reloc_value */ diff --git a/drivers/staging/tidspbridge/dynload/reloc_table.h b/drivers/staging/tidspbridge/dynload/reloc_table.h deleted file mode 100644 index 6aab03d4668d..000000000000 --- a/drivers/staging/tidspbridge/dynload/reloc_table.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * reloc_table.h - * - * 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. - */ - -#ifndef _RELOC_TABLE_H_ -#define _RELOC_TABLE_H_ -/* - * Table of relocation operator properties - */ -#include <linux/types.h> - -/* How does this relocation operation access the program image? */ -#define ROP_N 0 /* does not access image */ -#define ROP_R 1 /* read from image */ -#define ROP_W 2 /* write to image */ -#define ROP_RW 3 /* read from and write to image */ - -/* For program image access, what are the overflow rules for the bit field? */ -/* Beware! Procedure repack depends on this encoding */ -#define ROP_ANY 0 /* no overflow ever, just truncate the value */ -#define ROP_SGN 1 /* signed field */ -#define ROP_UNS 2 /* unsigned field */ -#define ROP_MAX 3 /* allow maximum range of either signed or unsigned */ - -/* How does the relocation operation use the symbol reference */ -#define ROP_IGN 0 /* no symbol is referenced */ -#define ROP_LIT 0 /* use rp->UVAL literal field */ -#define ROP_SYM 1 /* symbol value is used in relocation */ -#define ROP_SYMD 2 /* delta value vs last link is used */ - -/* How does the reloc op use the stack? */ -#define RSTK_N 0 /* Does not use */ -#define RSTK_POP 1 /* Does a POP */ -#define RSTK_UOP 2 /* Unary op, stack position unaffected */ -#define RSTK_PSH 3 /* Does a push */ - -/* - * Computational actions performed by the dynamic loader - */ -enum dload_actions { - /* don't alter the current val (from stack or mem fetch) */ - RACT_VAL, - /* set value to reference amount (from symbol reference) */ - RACT_ASGN, - RACT_ADD, /* add reference to value */ - RACT_PCR, /* add reference minus PC delta to value */ - RACT_ADDISP, /* add reference plus R_DISP */ - RACT_ASGPC, /* set value to section addr plus reference */ - - RACT_PLUS, /* stack + */ - RACT_SUB, /* stack - */ - RACT_NEG, /* stack unary - */ - - RACT_MPY, /* stack * */ - RACT_DIV, /* stack / */ - RACT_MOD, /* stack % */ - - RACT_SR, /* stack unsigned >> */ - RACT_ASR, /* stack signed >> */ - RACT_SL, /* stack << */ - RACT_AND, /* stack & */ - RACT_OR, /* stack | */ - RACT_XOR, /* stack ^ */ - RACT_NOT, /* stack ~ */ - RACT_C6SECT, /* for C60 R_SECT op */ - RACT_C6BASE, /* for C60 R_BASE op */ - RACT_C6DSPL, /* for C60 scaled 15-bit displacement */ - RACT_PCR23T /* for ARM Thumb long branch */ -}; - -/* - * macros used to extract values - */ -#define RFV_POSN(aaa) ((aaa) & 0xF) -#define RFV_WIDTH(aaa) (((aaa) >> 4) & 0x3F) -#define RFV_ACTION(aaa) ((aaa) >> 10) - -#define RFV_SIGN(iii) (((iii) >> 2) & 0x3) -#define RFV_SYM(iii) (((iii) >> 4) & 0x3) -#define RFV_STK(iii) (((iii) >> 6) & 0x3) -#define RFV_ACCS(iii) ((iii) & 0x3) - -#if (TMS32060) -#define RFV_SCALE(iii) ((iii) >> 11) -#define RFV_BIGOFF(iii) (((iii) >> 8) & 0x7) -#else -#define RFV_BIGOFF(iii) ((iii) >> 8) -#endif - -#endif /* _RELOC_TABLE_H_ */ diff --git a/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c b/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c deleted file mode 100644 index a28bc0442491..000000000000 --- a/drivers/staging/tidspbridge/dynload/reloc_table_c6000.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * reloc_table_c6000.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. - */ - -/* Tables generated for c6000 */ - -#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63) -#define HASH_L(zz) ((zz) >> 8) -#define HASH_I(zz) ((zz) & 0xFF) - -static const u16 rop_map1[] = { - 0, - 1, - 2, - 20, - 4, - 5, - 6, - 15, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 17, - 18, - 19, - 21, - 16, - 16394, - 16404, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 32, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 40, - 112, - 113, - 65535, - 16384, - 16385, - 16386, - 16387, - 16388, - 16389, - 16390, - 16391, - 16392, - 16393, - 16395, - 16396, - 16397, - 16398, - 16399, - 16400, - 16401, - 16402, - 16403, - 16405, - 16406, - 65535, - 65535, - 65535 -}; - -static const s16 rop_map2[] = { - -256, - -255, - -254, - -245, - -253, - -252, - -251, - -250, - -241, - -240, - -239, - -238, - -237, - -236, - 1813, - 5142, - -248, - -247, - 778, - -244, - -249, - -221, - -211, - -1, - -1, - -1, - -1, - -1, - -1, - -243, - -1, - -1, - -1, - -1, - -1, - -1, - -242, - -233, - -232, - -1, - -231, - -230, - -229, - -228, - -227, - -226, - -225, - -224, - -223, - 5410, - -220, - -219, - -218, - -217, - -216, - -215, - -214, - -213, - 5676, - -210, - -209, - -1, - -1, - -1 -}; - -static const u16 rop_action[] = { - 2560, - 2304, - 2304, - 2432, - 2432, - 2560, - 2176, - 2304, - 2560, - 3200, - 3328, - 3584, - 3456, - 2304, - 4208, - 20788, - 21812, - 3415, - 3245, - 2311, - 4359, - 19764, - 2311, - 3191, - 3280, - 6656, - 7680, - 8704, - 9728, - 10752, - 11776, - 12800, - 13824, - 14848, - 15872, - 16896, - 17920, - 18944, - 0, - 0, - 0, - 0, - 1536, - 1536, - 1536, - 5632, - 512, - 0 -}; - -static const u16 rop_info[] = { - 0, - 35, - 35, - 35, - 35, - 35, - 35, - 35, - 35, - 39, - 39, - 39, - 39, - 35, - 34, - 283, - 299, - 4135, - 4391, - 291, - 33059, - 283, - 295, - 4647, - 4135, - 64, - 64, - 128, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 64, - 128, - 201, - 197, - 74, - 70, - 208, - 196, - 200, - 192, - 192, - 66 -}; diff --git a/drivers/staging/tidspbridge/dynload/tramp.c b/drivers/staging/tidspbridge/dynload/tramp.c deleted file mode 100644 index 5f0431305fbb..000000000000 --- a/drivers/staging/tidspbridge/dynload/tramp.c +++ /dev/null @@ -1,1143 +0,0 @@ -/* - * tramp.c - * - * DSP-BIOS Bridge driver support functions for TI OMAP processors. - * - * Copyright (C) 2009 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 "header.h" - -#if TMS32060 -#include "tramp_table_c6000.c" -#endif - -#define MAX_RELOS_PER_PASS 4 - -/* - * Function: priv_tramp_sect_tgt_alloc - * Description: Allocate target memory for the trampoline section. The - * target mem size is easily obtained as the next available address. - */ -static int priv_tramp_sect_tgt_alloc(struct dload_state *dlthis) -{ - int ret_val = 0; - struct ldr_section_info *sect_info; - - /* Populate the trampoline loader section and allocate it on the - * target. The section name is ALWAYS the first string in the final - * string table for trampolines. The trampoline section is always - * 1 beyond the total number of allocated sections. */ - sect_info = &dlthis->ldr_sections[dlthis->allocated_secn_count]; - - sect_info->name = dlthis->tramp.final_string_table; - sect_info->size = dlthis->tramp.tramp_sect_next_addr; - sect_info->context = 0; - sect_info->type = - (4 << 8) | DLOAD_TEXT | DS_ALLOCATE_MASK | DS_DOWNLOAD_MASK; - sect_info->page = 0; - sect_info->run_addr = 0; - sect_info->load_addr = 0; - ret_val = dlthis->myalloc->dload_allocate(dlthis->myalloc, - sect_info, - ds_alignment - (sect_info->type)); - - if (ret_val == 0) - dload_error(dlthis, "Failed to allocate target memory for" - " trampoline"); - - return ret_val; -} - -/* - * Function: priv_h2a - * Description: Helper function to convert a hex value to its ASCII - * representation. Used for trampoline symbol name generation. - */ -static u8 priv_h2a(u8 value) -{ - if (value > 0xF) - return 0xFF; - - if (value <= 9) - value += 0x30; - else - value += 0x37; - - return value; -} - -/* - * Function: priv_tramp_sym_gen_name - * Description: Generate a trampoline symbol name (ASCII) using the value - * of the symbol. This places the new name into the user buffer. - * The name is fixed in length and of the form: __$dbTR__xxxxxxxx - * (where "xxxxxxxx" is the hex value). - */ -static void priv_tramp_sym_gen_name(u32 value, char *dst) -{ - u32 i; - char *prefix = TRAMP_SYM_PREFIX; - char *dst_local = dst; - u8 tmp; - - /* Clear out the destination, including the ending NULL */ - for (i = 0; i < (TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN); i++) - *(dst_local + i) = 0; - - /* Copy the prefix to start */ - for (i = 0; i < strlen(TRAMP_SYM_PREFIX); i++) { - *dst_local = *(prefix + i); - dst_local++; - } - - /* Now convert the value passed in to a string equiv of the hex */ - for (i = 0; i < sizeof(value); i++) { -#ifndef _BIG_ENDIAN - tmp = *(((u8 *) &value) + (sizeof(value) - 1) - i); - *dst_local = priv_h2a((tmp & 0xF0) >> 4); - dst_local++; - *dst_local = priv_h2a(tmp & 0x0F); - dst_local++; -#else - tmp = *(((u8 *) &value) + i); - *dst_local = priv_h2a((tmp & 0xF0) >> 4); - dst_local++; - *dst_local = priv_h2a(tmp & 0x0F); - dst_local++; -#endif - } - - /* NULL terminate */ - *dst_local = 0; -} - -/* - * Function: priv_tramp_string_create - * Description: Create a new string specific to the trampoline loading and add - * it to the trampoline string list. This list contains the - * trampoline section name and trampoline point symbols. - */ -static struct tramp_string *priv_tramp_string_create(struct dload_state *dlthis, - u32 str_len, char *str) -{ - struct tramp_string *new_string = NULL; - u32 i; - - /* Create a new string object with the specified size. */ - new_string = - (struct tramp_string *)dlthis->mysym->dload_allocate(dlthis->mysym, - (sizeof - (struct - tramp_string) - + str_len + - 1)); - if (new_string != NULL) { - /* Clear the string first. This ensures the ending NULL is - * present and the optimizer won't touch it. */ - for (i = 0; i < (sizeof(struct tramp_string) + str_len + 1); - i++) - *((u8 *) new_string + i) = 0; - - /* Add this string to our virtual table by assigning it the - * next index and pushing it to the tail of the list. */ - new_string->index = dlthis->tramp.tramp_string_next_index; - dlthis->tramp.tramp_string_next_index++; - dlthis->tramp.tramp_string_size += str_len + 1; - - new_string->next = NULL; - if (dlthis->tramp.string_head == NULL) - dlthis->tramp.string_head = new_string; - else - dlthis->tramp.string_tail->next = new_string; - - dlthis->tramp.string_tail = new_string; - - /* Copy the string over to the new object */ - for (i = 0; i < str_len; i++) - new_string->str[i] = str[i]; - } - - return new_string; -} - -/* - * Function: priv_tramp_string_find - * Description: Walk the trampoline string list and find a match for the - * provided string. If not match is found, NULL is returned. - */ -static struct tramp_string *priv_tramp_string_find(struct dload_state *dlthis, - char *str) -{ - struct tramp_string *cur_str = NULL; - struct tramp_string *ret_val = NULL; - u32 i; - u32 str_len = strlen(str); - - for (cur_str = dlthis->tramp.string_head; - (ret_val == NULL) && (cur_str != NULL); cur_str = cur_str->next) { - /* If the string lengths aren't equal, don't bother - * comparing */ - if (str_len != strlen(cur_str->str)) - continue; - - /* Walk the strings until one of them ends */ - for (i = 0; i < str_len; i++) { - /* If they don't match in the current position then - * break out now, no sense in continuing to look at - * this string. */ - if (str[i] != cur_str->str[i]) - break; - } - - if (i == str_len) - ret_val = cur_str; - } - - return ret_val; -} - -/* - * Function: priv_string_tbl_finalize - * Description: Flatten the trampoline string list into a table of NULL - * terminated strings. This is the same format of string table - * as used by the COFF/DOFF file. - */ -static int priv_string_tbl_finalize(struct dload_state *dlthis) -{ - int ret_val = 0; - struct tramp_string *cur_string; - char *cur_loc; - char *tmp; - - /* Allocate enough space for all strings that have been created. The - * table is simply all strings concatenated together will NULL - * endings. */ - dlthis->tramp.final_string_table = - (char *)dlthis->mysym->dload_allocate(dlthis->mysym, - dlthis->tramp. - tramp_string_size); - if (dlthis->tramp.final_string_table != NULL) { - /* We got our buffer, walk the list and release the nodes as* - * we go */ - cur_loc = dlthis->tramp.final_string_table; - cur_string = dlthis->tramp.string_head; - while (cur_string != NULL) { - /* Move the head/tail pointers */ - dlthis->tramp.string_head = cur_string->next; - if (dlthis->tramp.string_tail == cur_string) - dlthis->tramp.string_tail = NULL; - - /* Copy the string contents */ - for (tmp = cur_string->str; - *tmp != '\0'; tmp++, cur_loc++) - *cur_loc = *tmp; - - /* Pick up the NULL termination since it was missed by - * breaking using it to end the above loop. */ - *cur_loc = '\0'; - cur_loc++; - - /* Free the string node, we don't need it any more. */ - dlthis->mysym->dload_deallocate(dlthis->mysym, - cur_string); - - /* Move our pointer to the next one */ - cur_string = dlthis->tramp.string_head; - } - - /* Update our return value to success */ - ret_val = 1; - } else - dload_error(dlthis, "Failed to allocate trampoline " - "string table"); - - return ret_val; -} - -/* - * Function: priv_tramp_sect_alloc - * Description: Virtually allocate space from the trampoline section. This - * function returns the next offset within the trampoline section - * that is available and moved the next available offset by the - * requested size. NO TARGET ALLOCATION IS DONE AT THIS TIME. - */ -static u32 priv_tramp_sect_alloc(struct dload_state *dlthis, u32 tramp_size) -{ - u32 ret_val; - - /* If the next available address is 0, this is our first allocation. - * Create a section name string to go into the string table . */ - if (dlthis->tramp.tramp_sect_next_addr == 0) { - dload_syms_error(dlthis->mysym, "*** WARNING *** created " - "dynamic TRAMPOLINE section for module %s", - dlthis->str_head); - } - - /* Reserve space for the new trampoline */ - ret_val = dlthis->tramp.tramp_sect_next_addr; - dlthis->tramp.tramp_sect_next_addr += tramp_size; - return ret_val; -} - -/* - * Function: priv_tramp_sym_create - * Description: Allocate and create a new trampoline specific symbol and add - * it to the trampoline symbol list. These symbols will include - * trampoline points as well as the external symbols they - * reference. - */ -static struct tramp_sym *priv_tramp_sym_create(struct dload_state *dlthis, - u32 str_index, - struct local_symbol *tmp_sym) -{ - struct tramp_sym *new_sym = NULL; - u32 i; - - /* Allocate new space for the symbol in the symbol table. */ - new_sym = - (struct tramp_sym *)dlthis->mysym->dload_allocate(dlthis->mysym, - sizeof(struct tramp_sym)); - if (new_sym != NULL) { - for (i = 0; i != sizeof(struct tramp_sym); i++) - *((char *)new_sym + i) = 0; - - /* Assign this symbol the next symbol index for easier - * reference later during relocation. */ - new_sym->index = dlthis->tramp.tramp_sym_next_index; - dlthis->tramp.tramp_sym_next_index++; - - /* Populate the symbol information. At this point any - * trampoline symbols will be the offset location, not the - * final. Copy over the symbol info to start, then be sure to - * get the string index from the trampoline string table. */ - new_sym->sym_info = *tmp_sym; - new_sym->str_index = str_index; - - /* Push the new symbol to the tail of the symbol table list */ - new_sym->next = NULL; - if (dlthis->tramp.symbol_head == NULL) - dlthis->tramp.symbol_head = new_sym; - else - dlthis->tramp.symbol_tail->next = new_sym; - - dlthis->tramp.symbol_tail = new_sym; - } - - return new_sym; -} - -/* - * Function: priv_tramp_sym_get - * Description: Search for the symbol with the matching string index (from - * the trampoline string table) and return the trampoline - * symbol object, if found. Otherwise return NULL. - */ -static struct tramp_sym *priv_tramp_sym_get(struct dload_state *dlthis, - u32 string_index) -{ - struct tramp_sym *sym_found = NULL; - - /* Walk the symbol table list and search vs. the string index */ - for (sym_found = dlthis->tramp.symbol_head; - sym_found != NULL; sym_found = sym_found->next) { - if (sym_found->str_index == string_index) - break; - } - - return sym_found; -} - -/* - * Function: priv_tramp_sym_find - * Description: Search for a trampoline symbol based on the string name of - * the symbol. Return the symbol object, if found, otherwise - * return NULL. - */ -static struct tramp_sym *priv_tramp_sym_find(struct dload_state *dlthis, - char *string) -{ - struct tramp_sym *sym_found = NULL; - struct tramp_string *str_found = NULL; - - /* First, search for the string, then search for the sym based on the - string index. */ - str_found = priv_tramp_string_find(dlthis, string); - if (str_found != NULL) - sym_found = priv_tramp_sym_get(dlthis, str_found->index); - - return sym_found; -} - -/* - * Function: priv_tramp_sym_finalize - * Description: Allocate a flat symbol table for the trampoline section, - * put each trampoline symbol into the table, adjust the - * symbol value based on the section address on the target and - * free the trampoline symbol list nodes. - */ -static int priv_tramp_sym_finalize(struct dload_state *dlthis) -{ - int ret_val = 0; - struct tramp_sym *cur_sym; - struct ldr_section_info *tramp_sect = - &dlthis->ldr_sections[dlthis->allocated_secn_count]; - struct local_symbol *new_sym; - - /* Allocate a table to hold a flattened version of all symbols - * created. */ - dlthis->tramp.final_sym_table = - (struct local_symbol *)dlthis->mysym->dload_allocate(dlthis->mysym, - (sizeof(struct local_symbol) * dlthis->tramp. - tramp_sym_next_index)); - if (dlthis->tramp.final_sym_table != NULL) { - /* Walk the list of all symbols, copy it over to the flattened - * table. After it has been copied, the node can be freed as - * it is no longer needed. */ - new_sym = dlthis->tramp.final_sym_table; - cur_sym = dlthis->tramp.symbol_head; - while (cur_sym != NULL) { - /* Pop it off the list */ - dlthis->tramp.symbol_head = cur_sym->next; - if (cur_sym == dlthis->tramp.symbol_tail) - dlthis->tramp.symbol_tail = NULL; - - /* Copy the symbol contents into the flat table */ - *new_sym = cur_sym->sym_info; - - /* Now finalize the symbol. If it is in the tramp - * section, we need to adjust for the section start. - * If it is external then we don't need to adjust at - * all. - * NOTE: THIS CODE ASSUMES THAT THE TRAMPOLINE IS - * REFERENCED LIKE A CALL TO AN EXTERNAL SO VALUE AND - * DELTA ARE THE SAME. SEE THE FUNCTION dload_symbols - * WHERE DN_UNDEF IS HANDLED FOR MORE REFERENCE. */ - if (new_sym->secnn < 0) { - new_sym->value += tramp_sect->load_addr; - new_sym->delta = new_sym->value; - } - - /* Let go of the symbol node */ - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym); - - /* Move to the next node */ - cur_sym = dlthis->tramp.symbol_head; - new_sym++; - } - - ret_val = 1; - } else - dload_error(dlthis, "Failed to alloc trampoline sym table"); - - return ret_val; -} - -/* - * Function: priv_tgt_img_gen - * Description: Allocate storage for and copy the target specific image data - * and fix up its relocations for the new external symbol. If - * a trampoline image packet was successfully created it is added - * to the trampoline list. - */ -static int priv_tgt_img_gen(struct dload_state *dlthis, u32 base, - u32 gen_index, struct tramp_sym *new_ext_sym) -{ - struct tramp_img_pkt *new_img_pkt = NULL; - u32 i; - u32 pkt_size = tramp_img_pkt_size_get(); - u8 *gen_tbl_entry; - u8 *pkt_data; - struct reloc_record_t *cur_relo; - int ret_val = 0; - - /* Allocate a new image packet and set it up. */ - new_img_pkt = - (struct tramp_img_pkt *)dlthis->mysym->dload_allocate(dlthis->mysym, - pkt_size); - if (new_img_pkt != NULL) { - /* Save the base, this is where it goes in the section */ - new_img_pkt->base = base; - - /* Copy over the image data and relos from the target table */ - pkt_data = (u8 *) &new_img_pkt->hdr; - gen_tbl_entry = (u8 *) &tramp_gen_info[gen_index]; - for (i = 0; i < pkt_size; i++) { - *pkt_data = *gen_tbl_entry; - pkt_data++; - gen_tbl_entry++; - } - - /* Update the relocations to point to the external symbol */ - cur_relo = - (struct reloc_record_t *)((u8 *) &new_img_pkt->hdr + - new_img_pkt->hdr.relo_offset); - for (i = 0; i < new_img_pkt->hdr.num_relos; i++) - cur_relo[i].SYMNDX = new_ext_sym->index; - - /* Add it to the trampoline list. */ - new_img_pkt->next = dlthis->tramp.tramp_pkts; - dlthis->tramp.tramp_pkts = new_img_pkt; - - ret_val = 1; - } - - return ret_val; -} - -/* - * Function: priv_pkt_relo - * Description: Take the provided image data and the collection of relocations - * for it and perform the relocations. Note that all relocations - * at this stage are considered SECOND PASS since the original - * image has already been processed in the first pass. This means - * TRAMPOLINES ARE TREATED AS 2ND PASS even though this is really - * the first (and only) relocation that will be performed on them. - */ -static int priv_pkt_relo(struct dload_state *dlthis, tgt_au_t *data, - struct reloc_record_t *rp[], u32 relo_count) -{ - int ret_val = 1; - u32 i; - bool tmp; - - /* Walk through all of the relos and process them. This function is - * the equivalent of relocate_packet() from cload.c, but specialized - * for trampolines and 2nd phase relocations. */ - for (i = 0; i < relo_count; i++) - dload_relocate(dlthis, data, rp[i], &tmp, true); - - return ret_val; -} - -/* - * Function: priv_tramp_pkt_finalize - * Description: Walk the list of all trampoline packets and finalize them. - * Each trampoline image packet will be relocated now that the - * trampoline section has been allocated on the target. Once - * all of the relocations are done the trampoline image data - * is written into target memory and the trampoline packet - * is freed: it is no longer needed after this point. - */ -static int priv_tramp_pkt_finalize(struct dload_state *dlthis) -{ - int ret_val = 1; - struct tramp_img_pkt *cur_pkt = NULL; - struct reloc_record_t *relos[MAX_RELOS_PER_PASS]; - u32 relos_done; - u32 i; - struct reloc_record_t *cur_relo; - struct ldr_section_info *sect_info = - &dlthis->ldr_sections[dlthis->allocated_secn_count]; - - /* Walk the list of trampoline packets and relocate each packet. This - * function is the trampoline equivalent of dload_data() from - * cload.c. */ - cur_pkt = dlthis->tramp.tramp_pkts; - while ((ret_val != 0) && (cur_pkt != NULL)) { - /* Remove the pkt from the list */ - dlthis->tramp.tramp_pkts = cur_pkt->next; - - /* Setup section and image offset information for the relo */ - dlthis->image_secn = sect_info; - dlthis->image_offset = cur_pkt->base; - dlthis->delta_runaddr = sect_info->run_addr; - - /* Walk through all relos for the packet */ - relos_done = 0; - cur_relo = (struct reloc_record_t *)((u8 *) &cur_pkt->hdr + - cur_pkt->hdr.relo_offset); - while (relos_done < cur_pkt->hdr.num_relos) { -#ifdef ENABLE_TRAMP_DEBUG - dload_syms_error(dlthis->mysym, - "===> Trampoline %x branches to %x", - sect_info->run_addr + - dlthis->image_offset, - dlthis-> - tramp.final_sym_table[cur_relo-> - SYMNDX].value); -#endif - - for (i = 0; - ((i < MAX_RELOS_PER_PASS) && - ((i + relos_done) < cur_pkt->hdr.num_relos)); i++) - relos[i] = cur_relo + i; - - /* Do the actual relo */ - ret_val = priv_pkt_relo(dlthis, - (tgt_au_t *) &cur_pkt->payload, - relos, i); - if (ret_val == 0) { - dload_error(dlthis, - "Relocation of trampoline pkt at %x" - " failed", cur_pkt->base + - sect_info->run_addr); - break; - } - - relos_done += i; - cur_relo += i; - } - - /* Make sure we didn't hit a problem */ - if (ret_val != 0) { - /* Relos are done for the packet, write it to the - * target */ - ret_val = dlthis->myio->writemem(dlthis->myio, - &cur_pkt->payload, - sect_info->load_addr + - cur_pkt->base, - sect_info, - BYTE_TO_HOST - (cur_pkt->hdr. - tramp_code_size)); - if (ret_val == 0) { - dload_error(dlthis, - "Write to " FMT_UI32 " failed", - sect_info->load_addr + - cur_pkt->base); - } - - /* Done with the pkt, let it go */ - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt); - - /* Get the next packet to process */ - cur_pkt = dlthis->tramp.tramp_pkts; - } - } - - return ret_val; -} - -/* - * Function: priv_dup_pkt_finalize - * Description: Walk the list of duplicate image packets and finalize them. - * Each duplicate packet will be relocated again for the - * relocations that previously failed and have been adjusted - * to point at a trampoline. Once all relocations for a packet - * have been done, write the packet into target memory. The - * duplicate packet and its relocation chain are all freed - * after use here as they are no longer needed after this. - */ -static int priv_dup_pkt_finalize(struct dload_state *dlthis) -{ - int ret_val = 1; - struct tramp_img_dup_pkt *cur_pkt; - struct tramp_img_dup_relo *cur_relo; - struct reloc_record_t *relos[MAX_RELOS_PER_PASS]; - struct doff_scnhdr_t *sect_hdr = NULL; - s32 i; - - /* Similar to the trampoline pkt finalize, this function walks each dup - * pkt that was generated and performs all relocations that were - * deferred to a 2nd pass. This is the equivalent of dload_data() from - * cload.c, but does not need the additional reorder and checksum - * processing as it has already been done. */ - cur_pkt = dlthis->tramp.dup_pkts; - while ((ret_val != 0) && (cur_pkt != NULL)) { - /* Remove the node from the list, we'll be freeing it - * shortly */ - dlthis->tramp.dup_pkts = cur_pkt->next; - - /* Setup the section and image offset for relocation */ - dlthis->image_secn = &dlthis->ldr_sections[cur_pkt->secnn]; - dlthis->image_offset = cur_pkt->offset; - - /* In order to get the delta run address, we need to reference - * the original section header. It's a bit ugly, but needed - * for relo. */ - i = (s32) (dlthis->image_secn - dlthis->ldr_sections); - sect_hdr = dlthis->sect_hdrs + i; - dlthis->delta_runaddr = sect_hdr->ds_paddr; - - /* Walk all relos in the chain and process each. */ - cur_relo = cur_pkt->relo_chain; - while (cur_relo != NULL) { - /* Process them a chunk at a time to be efficient */ - for (i = 0; (i < MAX_RELOS_PER_PASS) - && (cur_relo != NULL); - i++, cur_relo = cur_relo->next) { - relos[i] = &cur_relo->relo; - cur_pkt->relo_chain = cur_relo->next; - } - - /* Do the actual relo */ - ret_val = priv_pkt_relo(dlthis, - cur_pkt->img_pkt.img_data, - relos, i); - if (ret_val == 0) { - dload_error(dlthis, - "Relocation of dup pkt at %x" - " failed", cur_pkt->offset + - dlthis->image_secn->run_addr); - break; - } - - /* Release all of these relos, we're done with them */ - while (i > 0) { - dlthis->mysym->dload_deallocate(dlthis->mysym, - GET_CONTAINER - (relos[i - 1], - struct tramp_img_dup_relo, - relo)); - i--; - } - - /* DO NOT ADVANCE cur_relo, IT IS ALREADY READY TO - * GO! */ - } - - /* Done with all relos. Make sure we didn't have a problem and - * write it out to the target */ - if (ret_val != 0) { - ret_val = dlthis->myio->writemem(dlthis->myio, - cur_pkt->img_pkt. - img_data, - dlthis->image_secn-> - load_addr + - cur_pkt->offset, - dlthis->image_secn, - BYTE_TO_HOST - (cur_pkt->img_pkt. - packet_size)); - if (ret_val == 0) { - dload_error(dlthis, - "Write to " FMT_UI32 " failed", - dlthis->image_secn->load_addr + - cur_pkt->offset); - } - - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_pkt); - - /* Advance to the next packet */ - cur_pkt = dlthis->tramp.dup_pkts; - } - } - - return ret_val; -} - -/* - * Function: priv_dup_find - * Description: Walk the list of existing duplicate packets and find a - * match based on the section number and image offset. Return - * the duplicate packet if found, otherwise NULL. - */ -static struct tramp_img_dup_pkt *priv_dup_find(struct dload_state *dlthis, - s16 secnn, u32 image_offset) -{ - struct tramp_img_dup_pkt *cur_pkt = NULL; - - for (cur_pkt = dlthis->tramp.dup_pkts; - cur_pkt != NULL; cur_pkt = cur_pkt->next) { - if ((cur_pkt->secnn == secnn) && - (cur_pkt->offset == image_offset)) { - /* Found a match, break out */ - break; - } - } - - return cur_pkt; -} - -/* - * Function: priv_img_pkt_dup - * Description: Duplicate the original image packet. If this is the first - * time this image packet has been seen (based on section number - * and image offset), create a new duplicate packet and add it - * to the dup packet list. If not, just get the existing one and - * update it with the current packet contents (since relocation - * on the packet is still ongoing in first pass.) Create a - * duplicate of the provided relocation, but update it to point - * to the new trampoline symbol. Add the new relocation dup to - * the dup packet's relo chain for 2nd pass relocation later. - */ -static int priv_img_pkt_dup(struct dload_state *dlthis, - s16 secnn, u32 image_offset, - struct image_packet_t *ipacket, - struct reloc_record_t *rp, - struct tramp_sym *new_tramp_sym) -{ - struct tramp_img_dup_pkt *dup_pkt = NULL; - u32 new_dup_size; - s32 i; - int ret_val = 0; - struct tramp_img_dup_relo *dup_relo = NULL; - - /* Determine if this image packet is already being tracked in the - dup list for other trampolines. */ - dup_pkt = priv_dup_find(dlthis, secnn, image_offset); - - if (dup_pkt == NULL) { - /* This image packet does not exist in our tracking, so create - * a new one and add it to the head of the list. */ - new_dup_size = sizeof(struct tramp_img_dup_pkt) + - ipacket->packet_size; - - dup_pkt = (struct tramp_img_dup_pkt *) - dlthis->mysym->dload_allocate(dlthis->mysym, new_dup_size); - if (dup_pkt != NULL) { - /* Save off the section and offset information */ - dup_pkt->secnn = secnn; - dup_pkt->offset = image_offset; - dup_pkt->relo_chain = NULL; - - /* Copy the original packet content */ - dup_pkt->img_pkt = *ipacket; - dup_pkt->img_pkt.img_data = (u8 *) (dup_pkt + 1); - for (i = 0; i < ipacket->packet_size; i++) - *(dup_pkt->img_pkt.img_data + i) = - *(ipacket->img_data + i); - - /* Add the packet to the dup list */ - dup_pkt->next = dlthis->tramp.dup_pkts; - dlthis->tramp.dup_pkts = dup_pkt; - } else - dload_error(dlthis, "Failed to create dup packet!"); - } else { - /* The image packet contents could have changed since - * trampoline detection happens during relocation of the image - * packets. So, we need to update the image packet contents - * before adding relo information. */ - for (i = 0; i < dup_pkt->img_pkt.packet_size; i++) - *(dup_pkt->img_pkt.img_data + i) = - *(ipacket->img_data + i); - } - - /* Since the previous code may have allocated a new dup packet for us, - double check that we actually have one. */ - if (dup_pkt != NULL) { - /* Allocate a new node for the relo chain. Each image packet - * can potentially have multiple relocations that cause a - * trampoline to be generated. So, we keep them in a chain, - * order is not important. */ - dup_relo = dlthis->mysym->dload_allocate(dlthis->mysym, - sizeof(struct tramp_img_dup_relo)); - if (dup_relo != NULL) { - /* Copy the relo contents, adjust for the new - * trampoline and add it to the list. */ - dup_relo->relo = *rp; - dup_relo->relo.SYMNDX = new_tramp_sym->index; - - dup_relo->next = dup_pkt->relo_chain; - dup_pkt->relo_chain = dup_relo; - - /* That's it, we're done. Make sure we update our - * return value to be success since everything finished - * ok */ - ret_val = 1; - } else - dload_error(dlthis, "Unable to alloc dup relo"); - } - - return ret_val; -} - -/* - * Function: dload_tramp_avail - * Description: Check to see if the target supports a trampoline for this type - * of relocation. Return true if it does, otherwise false. - */ -bool dload_tramp_avail(struct dload_state *dlthis, struct reloc_record_t *rp) -{ - bool ret_val = false; - u16 map_index; - u16 gen_index; - - /* Check type hash vs. target tramp table */ - map_index = HASH_FUNC(rp->TYPE); - gen_index = tramp_map[map_index]; - if (gen_index != TRAMP_NO_GEN_AVAIL) - ret_val = true; - - return ret_val; -} - -/* - * Function: dload_tramp_generate - * Description: Create a new trampoline for the provided image packet and - * relocation causing problems. This will create the trampoline - * as well as duplicate/update the image packet and relocation - * causing the problem, which will be relo'd again during - * finalization. - */ -int dload_tramp_generate(struct dload_state *dlthis, s16 secnn, - u32 image_offset, struct image_packet_t *ipacket, - struct reloc_record_t *rp) -{ - u16 map_index; - u16 gen_index; - int ret_val = 1; - char tramp_sym_str[TRAMP_SYM_PREFIX_LEN + TRAMP_SYM_HEX_ASCII_LEN]; - struct local_symbol *ref_sym; - struct tramp_sym *new_tramp_sym; - struct tramp_sym *new_ext_sym; - struct tramp_string *new_tramp_str; - u32 new_tramp_base; - struct local_symbol tmp_sym; - struct local_symbol ext_tmp_sym; - - /* Hash the relo type to get our generator information */ - map_index = HASH_FUNC(rp->TYPE); - gen_index = tramp_map[map_index]; - if (gen_index != TRAMP_NO_GEN_AVAIL) { - /* If this is the first trampoline, create the section name in - * our string table for debug help later. */ - if (dlthis->tramp.string_head == NULL) { - priv_tramp_string_create(dlthis, - strlen(TRAMP_SECT_NAME), - TRAMP_SECT_NAME); - } -#ifdef ENABLE_TRAMP_DEBUG - dload_syms_error(dlthis->mysym, - "Trampoline at img loc %x, references %x", - dlthis->ldr_sections[secnn].run_addr + - image_offset + rp->vaddr, - dlthis->local_symtab[rp->SYMNDX].value); -#endif - - /* Generate the trampoline string, check if already defined. - * If the relo symbol index is -1, it means we need the section - * info for relo later. To do this we'll dummy up a symbol - * with the section delta and run addresses. */ - if (rp->SYMNDX == -1) { - ext_tmp_sym.value = - dlthis->ldr_sections[secnn].run_addr; - ext_tmp_sym.delta = dlthis->sect_hdrs[secnn].ds_paddr; - ref_sym = &ext_tmp_sym; - } else - ref_sym = &(dlthis->local_symtab[rp->SYMNDX]); - - priv_tramp_sym_gen_name(ref_sym->value, tramp_sym_str); - new_tramp_sym = priv_tramp_sym_find(dlthis, tramp_sym_str); - if (new_tramp_sym == NULL) { - /* If tramp string not defined, create it and a new - * string, and symbol for it as well as the original - * symbol which caused the trampoline. */ - new_tramp_str = priv_tramp_string_create(dlthis, - strlen - (tramp_sym_str), - tramp_sym_str); - if (new_tramp_str == NULL) { - dload_error(dlthis, "Failed to create new " - "trampoline string\n"); - ret_val = 0; - } else { - /* Allocate tramp section space for the new - * tramp from the target */ - new_tramp_base = priv_tramp_sect_alloc(dlthis, - tramp_size_get()); - - /* We have a string, create the new symbol and - * duplicate the external. */ - tmp_sym.value = new_tramp_base; - tmp_sym.delta = 0; - tmp_sym.secnn = -1; - tmp_sym.sclass = 0; - new_tramp_sym = priv_tramp_sym_create(dlthis, - new_tramp_str-> - index, - &tmp_sym); - - new_ext_sym = priv_tramp_sym_create(dlthis, -1, - ref_sym); - - if ((new_tramp_sym != NULL) && - (new_ext_sym != NULL)) { - /* Call the image generator to get the - * new image data and fix up its - * relocations for the external - * symbol. */ - ret_val = priv_tgt_img_gen(dlthis, - new_tramp_base, - gen_index, - new_ext_sym); - - /* Add generated image data to tramp - * image list */ - if (ret_val != 1) { - dload_error(dlthis, "Failed to " - "create img pkt for" - " trampoline\n"); - } - } else { - dload_error(dlthis, "Failed to create " - "new tramp syms " - "(%8.8X, %8.8X)\n", - new_tramp_sym, new_ext_sym); - ret_val = 0; - } - } - } - - /* Duplicate the image data and relo record that caused the - * tramp, including update the relo data to point to the tramp - * symbol. */ - if (ret_val == 1) { - ret_val = priv_img_pkt_dup(dlthis, secnn, image_offset, - ipacket, rp, new_tramp_sym); - if (ret_val != 1) { - dload_error(dlthis, "Failed to create dup of " - "original img pkt\n"); - } - } - } - - return ret_val; -} - -/* - * Function: dload_tramp_pkt_update - * Description: Update the duplicate copy of this image packet, which the - * trampoline layer is already tracking. This call is critical - * to make if trampolines were generated anywhere within the - * packet and first pass relo continued on the remainder. The - * trampoline layer needs the updates image data so when 2nd - * pass relo is done during finalize the image packet can be - * written to the target since all relo is done. - */ -int dload_tramp_pkt_udpate(struct dload_state *dlthis, s16 secnn, - u32 image_offset, struct image_packet_t *ipacket) -{ - struct tramp_img_dup_pkt *dup_pkt = NULL; - s32 i; - int ret_val = 0; - - /* Find the image packet in question, the caller needs us to update it - since a trampoline was previously generated. */ - dup_pkt = priv_dup_find(dlthis, secnn, image_offset); - if (dup_pkt != NULL) { - for (i = 0; i < dup_pkt->img_pkt.packet_size; i++) - *(dup_pkt->img_pkt.img_data + i) = - *(ipacket->img_data + i); - - ret_val = 1; - } else { - dload_error(dlthis, - "Unable to find existing DUP pkt for %x, offset %x", - secnn, image_offset); - - } - - return ret_val; -} - -/* - * Function: dload_tramp_finalize - * Description: If any trampolines were created, finalize everything on the - * target by allocating the trampoline section on the target, - * finalizing the trampoline symbols, finalizing the trampoline - * packets (write the new section to target memory) and finalize - * the duplicate packets by doing 2nd pass relo over them. - */ -int dload_tramp_finalize(struct dload_state *dlthis) -{ - int ret_val = 1; - - if (dlthis->tramp.tramp_sect_next_addr != 0) { - /* Finalize strings into a flat table. This is needed so it - * can be added to the debug string table later. */ - ret_val = priv_string_tbl_finalize(dlthis); - - /* Do target allocation for section BEFORE finalizing - * symbols. */ - if (ret_val != 0) - ret_val = priv_tramp_sect_tgt_alloc(dlthis); - - /* Finalize symbols with their correct target information and - * flatten */ - if (ret_val != 0) - ret_val = priv_tramp_sym_finalize(dlthis); - - /* Finalize all trampoline packets. This performs the - * relocation on the packets as well as writing them to target - * memory. */ - if (ret_val != 0) - ret_val = priv_tramp_pkt_finalize(dlthis); - - /* Perform a 2nd pass relocation on the dup list. */ - if (ret_val != 0) - ret_val = priv_dup_pkt_finalize(dlthis); - } - - return ret_val; -} - -/* - * Function: dload_tramp_cleanup - * Description: Release all temporary resources used in the trampoline layer. - * Note that the target memory which may have been allocated and - * written to store the trampolines is NOT RELEASED HERE since it - * is potentially still in use. It is automatically released - * when the module is unloaded. - */ -void dload_tramp_cleanup(struct dload_state *dlthis) -{ - struct tramp_info *tramp = &dlthis->tramp; - struct tramp_sym *cur_sym; - struct tramp_string *cur_string; - struct tramp_img_pkt *cur_tramp_pkt; - struct tramp_img_dup_pkt *cur_dup_pkt; - struct tramp_img_dup_relo *cur_dup_relo; - - /* If there were no tramps generated, just return */ - if (tramp->tramp_sect_next_addr == 0) - return; - - /* Destroy all tramp information */ - for (cur_sym = tramp->symbol_head; - cur_sym != NULL; cur_sym = tramp->symbol_head) { - tramp->symbol_head = cur_sym->next; - if (tramp->symbol_tail == cur_sym) - tramp->symbol_tail = NULL; - - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_sym); - } - - if (tramp->final_sym_table != NULL) - dlthis->mysym->dload_deallocate(dlthis->mysym, - tramp->final_sym_table); - - for (cur_string = tramp->string_head; - cur_string != NULL; cur_string = tramp->string_head) { - tramp->string_head = cur_string->next; - if (tramp->string_tail == cur_string) - tramp->string_tail = NULL; - - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_string); - } - - if (tramp->final_string_table != NULL) - dlthis->mysym->dload_deallocate(dlthis->mysym, - tramp->final_string_table); - - for (cur_tramp_pkt = tramp->tramp_pkts; - cur_tramp_pkt != NULL; cur_tramp_pkt = tramp->tramp_pkts) { - tramp->tramp_pkts = cur_tramp_pkt->next; - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_tramp_pkt); - } - - for (cur_dup_pkt = tramp->dup_pkts; - cur_dup_pkt != NULL; cur_dup_pkt = tramp->dup_pkts) { - tramp->dup_pkts = cur_dup_pkt->next; - - for (cur_dup_relo = cur_dup_pkt->relo_chain; - cur_dup_relo != NULL; - cur_dup_relo = cur_dup_pkt->relo_chain) { - cur_dup_pkt->relo_chain = cur_dup_relo->next; - dlthis->mysym->dload_deallocate(dlthis->mysym, - cur_dup_relo); - } - - dlthis->mysym->dload_deallocate(dlthis->mysym, cur_dup_pkt); - } -} diff --git a/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c b/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c deleted file mode 100644 index 09cc64f213c0..000000000000 --- a/drivers/staging/tidspbridge/dynload/tramp_table_c6000.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * tramp_table_c6000.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 "dload_internal.h" - -/* These are defined in coff.h, but may not be available on all platforms - so we'll go ahead and define them here. */ -#ifndef R_C60LO16 -#define R_C60LO16 0x54 /* C60: MVK Low Half Register */ -#define R_C60HI16 0x55 /* C60: MVKH/MVKLH High Half Register */ -#endif - -#define C6X_TRAMP_WORD_COUNT 8 -#define C6X_TRAMP_MAX_RELOS 8 - -/* THIS HASH FUNCTION MUST MATCH THE ONE reloc_table_c6000.c */ -#define HASH_FUNC(zz) (((((zz) + 1) * 1845UL) >> 11) & 63) - -/* THIS MUST MATCH reloc_record_t FOR A SYMBOL BASED RELO */ -struct c6000_relo_record { - s32 vaddr; - s32 symndx; -#ifndef _BIG_ENDIAN - u16 disp; - u16 type; -#else - u16 type; - u16 disp; -#endif -}; - -struct c6000_gen_code { - struct tramp_gen_code_hdr hdr; - u32 tramp_instrs[C6X_TRAMP_WORD_COUNT]; - struct c6000_relo_record relos[C6X_TRAMP_MAX_RELOS]; -}; - -/* Hash mapping for relos that can cause trampolines. */ -static const u16 tramp_map[] = { - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 0, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535, - 65535 -}; - -static const struct c6000_gen_code tramp_gen_info[] = { - /* Tramp caused by R_C60PCR21 */ - { - /* Header - 8 instructions, 2 relos */ - { - sizeof(u32) * C6X_TRAMP_WORD_COUNT, - 2, - FIELD_OFFSET(struct c6000_gen_code, relos) - }, - - /* Trampoline instructions */ - { - 0x053C54F7, /* STW.D2T2 B10, *sp--[2] */ - 0x0500002A, /* || MVK.S2 <blank>, B10 */ - 0x0500006A, /* MVKH.S2 <blank>, B10 */ - 0x00280362, /* B.S2 B10 */ - 0x053C52E6, /* LDW.D2T2 *++sp[2], B10 */ - 0x00006000, /* NOP 4 */ - 0x00000000, /* NOP */ - 0x00000000 /* NOP */ - }, - - /* Relocations */ - { - {4, 0, 0, R_C60LO16}, - {8, 0, 0, R_C60HI16}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000}, - {0, 0, 0, 0x0000} - } - } -}; - -/* TARGET SPECIFIC FUNCTIONS THAT MUST BE DEFINED */ -static u32 tramp_size_get(void) -{ - return sizeof(u32) * C6X_TRAMP_WORD_COUNT; -} - -static u32 tramp_img_pkt_size_get(void) -{ - return sizeof(struct c6000_gen_code); -} |