493 lines
19 KiB
C
493 lines
19 KiB
C
/*
|
|
* dynamic_loader.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.
|
|
*/
|
|
|
|
#ifndef _DYNAMIC_LOADER_H_
|
|
#define _DYNAMIC_LOADER_H_
|
|
#include <linux/kernel.h>
|
|
#include <linux/types.h>
|
|
|
|
/*
|
|
* Dynamic Loader
|
|
*
|
|
* The function of the dynamic loader is to load a "module" containing
|
|
* instructions for a "target" processor into that processor. In the process
|
|
* it assigns memory for the module, resolves symbol references made by the
|
|
* module, and remembers symbols defined by the module.
|
|
*
|
|
* The dynamic loader is parameterized for a particular system by 4 classes
|
|
* that supply the module and system specific functions it requires
|
|
*/
|
|
/* The read functions for the module image to be loaded */
|
|
struct dynamic_loader_stream;
|
|
|
|
/* This class defines "host" symbol and support functions */
|
|
struct dynamic_loader_sym;
|
|
|
|
/* This class defines the allocator for "target" memory */
|
|
struct dynamic_loader_allocate;
|
|
|
|
/* This class defines the copy-into-target-memory functions */
|
|
struct dynamic_loader_initialize;
|
|
|
|
/*
|
|
* Option flags to modify the behavior of module loading
|
|
*/
|
|
#define DLOAD_INITBSS 0x1 /* initialize BSS sections to zero */
|
|
#define DLOAD_BIGEND 0x2 /* require big-endian load module */
|
|
#define DLOAD_LITTLE 0x4 /* require little-endian load module */
|
|
|
|
/*****************************************************************************
|
|
* 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, or NULL for symbol read only
|
|
* 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().
|
|
**************************************************************************** */
|
|
extern int dynamic_load_module(
|
|
/* the source for the module image */
|
|
struct dynamic_loader_stream *module,
|
|
/* host support for symbols and storage */
|
|
struct dynamic_loader_sym *syms,
|
|
/* the target memory allocator */
|
|
struct dynamic_loader_allocate *alloc,
|
|
/* the target memory initializer */
|
|
struct dynamic_loader_initialize *init,
|
|
unsigned options, /* option flags */
|
|
/* the returned module handle */
|
|
void **mhandle);
|
|
|
|
/*****************************************************************************
|
|
* 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, or NULL for symbol read only
|
|
* 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().
|
|
**************************************************************************** */
|
|
extern int dynamic_open_module(
|
|
/* the source for the module image */
|
|
struct dynamic_loader_stream *module,
|
|
/* host support for symbols and storage */
|
|
struct dynamic_loader_sym *syms,
|
|
/* the target memory allocator */
|
|
struct dynamic_loader_allocate *alloc,
|
|
/* the target memory initializer */
|
|
struct dynamic_loader_initialize *init,
|
|
unsigned options, /* option flags */
|
|
/* the returned module handle */
|
|
void **mhandle);
|
|
|
|
/*****************************************************************************
|
|
* 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().
|
|
**************************************************************************** */
|
|
extern int dynamic_unload_module(void *mhandle, /* the module
|
|
* handle */
|
|
/* host support for symbols and
|
|
* storage */
|
|
struct dynamic_loader_sym *syms,
|
|
/* the target memory allocator */
|
|
struct dynamic_loader_allocate *alloc,
|
|
/* the target memory initializer */
|
|
struct dynamic_loader_initialize *init);
|
|
|
|
/*****************************************************************************
|
|
*****************************************************************************
|
|
* A class used by the dynamic loader for input of the module image
|
|
*****************************************************************************
|
|
**************************************************************************** */
|
|
struct dynamic_loader_stream {
|
|
/* public: */
|
|
/*************************************************************************
|
|
* read_buffer
|
|
*
|
|
* PARAMETERS :
|
|
* buffer Pointer to the buffer to fill
|
|
* bufsiz Amount of data desired in sizeof() units
|
|
*
|
|
* EFFECT :
|
|
* Reads the specified amount of data from the module input stream
|
|
* into the specified buffer. Returns the amount of data read in sizeof()
|
|
* units (which if less than the specification, represents an error).
|
|
*
|
|
* NOTES:
|
|
* In release 1 increments the file position by the number of bytes read
|
|
*
|
|
************************************************************************ */
|
|
int (*read_buffer) (struct dynamic_loader_stream *thisptr,
|
|
void *buffer, unsigned bufsiz);
|
|
|
|
/*************************************************************************
|
|
* set_file_posn (release 1 only)
|
|
*
|
|
* PARAMETERS :
|
|
* posn Desired file position relative to start of file in sizeof() units.
|
|
*
|
|
* EFFECT :
|
|
* Adjusts the internal state of the stream object so that the next
|
|
* read_buffer call will begin to read at the specified offset from
|
|
* the beginning of the input module. Returns 0 for success, non-zero
|
|
* for failure.
|
|
*
|
|
************************************************************************ */
|
|
int (*set_file_posn) (struct dynamic_loader_stream *thisptr,
|
|
/* to be eliminated in release 2 */
|
|
unsigned int posn);
|
|
|
|
};
|
|
|
|
/*****************************************************************************
|
|
*****************************************************************************
|
|
* A class used by the dynamic loader for symbol table support and
|
|
* miscellaneous host-side functions
|
|
*****************************************************************************
|
|
**************************************************************************** */
|
|
|
|
typedef u32 ldr_addr;
|
|
|
|
/*
|
|
* the structure of a symbol known to the dynamic loader
|
|
*/
|
|
struct dynload_symbol {
|
|
ldr_addr value;
|
|
};
|
|
|
|
struct dynamic_loader_sym {
|
|
/* public: */
|
|
/*************************************************************************
|
|
* find_matching_symbol
|
|
*
|
|
* PARAMETERS :
|
|
* name The name of the desired symbol
|
|
*
|
|
* EFFECT :
|
|
* Locates a symbol matching the name specified. A pointer to the
|
|
* symbol is returned if it exists; 0 is returned if no such symbol is
|
|
* found.
|
|
*
|
|
************************************************************************ */
|
|
struct dynload_symbol *(*find_matching_symbol)
|
|
(struct dynamic_loader_sym *thisptr, const char *name);
|
|
|
|
/*************************************************************************
|
|
* add_to_symbol_table
|
|
*
|
|
* PARAMETERS :
|
|
* nname Pointer to the name of the new symbol
|
|
* moduleid An opaque module id assigned by the dynamic loader
|
|
*
|
|
* EFFECT :
|
|
* The new symbol is added to the table. A pointer to the symbol is
|
|
* returned, or NULL is returned for failure.
|
|
*
|
|
* NOTES:
|
|
* It is permissible for this function to return NULL; the effect is that
|
|
* the named symbol will not be available to resolve references in
|
|
* subsequent loads. Returning NULL will not cause the current load
|
|
* to fail.
|
|
************************************************************************ */
|
|
struct dynload_symbol *(*add_to_symbol_table)
|
|
(struct dynamic_loader_sym *
|
|
thisptr, const char *nname, unsigned moduleid);
|
|
|
|
/*************************************************************************
|
|
* purge_symbol_table
|
|
*
|
|
* PARAMETERS :
|
|
* moduleid An opaque module id assigned by the dynamic loader
|
|
*
|
|
* EFFECT :
|
|
* Each symbol in the symbol table whose moduleid matches the argument
|
|
* is removed from the table.
|
|
************************************************************************ */
|
|
void (*purge_symbol_table) (struct dynamic_loader_sym *thisptr,
|
|
unsigned moduleid);
|
|
|
|
/*************************************************************************
|
|
* dload_allocate
|
|
*
|
|
* PARAMETERS :
|
|
* memsiz size of desired memory in sizeof() units
|
|
*
|
|
* EFFECT :
|
|
* Returns a pointer to some "host" memory for use by the dynamic
|
|
* loader, or NULL for failure.
|
|
* This function is serves as a replaceable form of "malloc" to
|
|
* allow the user to configure the memory usage of the dynamic loader.
|
|
************************************************************************ */
|
|
void *(*dload_allocate) (struct dynamic_loader_sym *thisptr,
|
|
unsigned memsiz);
|
|
|
|
/*************************************************************************
|
|
* dload_deallocate
|
|
*
|
|
* PARAMETERS :
|
|
* memptr pointer to previously allocated memory
|
|
*
|
|
* EFFECT :
|
|
* Releases the previously allocated "host" memory.
|
|
************************************************************************ */
|
|
void (*dload_deallocate) (struct dynamic_loader_sym *thisptr,
|
|
void *memptr);
|
|
|
|
/*************************************************************************
|
|
* error_report
|
|
*
|
|
* PARAMETERS :
|
|
* errstr pointer to an error string
|
|
* args additional arguments
|
|
*
|
|
* EFFECT :
|
|
* This function provides an error reporting interface for the dynamic
|
|
* loader. The error string and arguments are designed as for the
|
|
* library function vprintf.
|
|
************************************************************************ */
|
|
void (*error_report) (struct dynamic_loader_sym *thisptr,
|
|
const char *errstr, va_list args);
|
|
|
|
}; /* class dynamic_loader_sym */
|
|
|
|
/*****************************************************************************
|
|
*****************************************************************************
|
|
* A class used by the dynamic loader to allocate and deallocate target memory.
|
|
*****************************************************************************
|
|
**************************************************************************** */
|
|
|
|
struct ldr_section_info {
|
|
/* Name of the memory section assigned at build time */
|
|
const char *name;
|
|
ldr_addr run_addr; /* execution address of the section */
|
|
ldr_addr load_addr; /* load address of the section */
|
|
ldr_addr size; /* size of the section in addressable units */
|
|
#ifndef _BIG_ENDIAN
|
|
u16 page; /* memory page or view */
|
|
u16 type; /* one of the section types below */
|
|
#else
|
|
u16 type; /* one of the section types below */
|
|
u16 page; /* memory page or view */
|
|
#endif
|
|
/* a context field for use by dynamic_loader_allocate;
|
|
* ignored but maintained by the dynamic loader */
|
|
u32 context;
|
|
};
|
|
|
|
/* use this macro to extract type of section from ldr_section_info.type field */
|
|
#define DLOAD_SECTION_TYPE(typeinfo) (typeinfo & 0xF)
|
|
|
|
/* type of section to be allocated */
|
|
#define DLOAD_TEXT 0
|
|
#define DLOAD_DATA 1
|
|
#define DLOAD_BSS 2
|
|
/* internal use only, run-time cinit will be of type DLOAD_DATA */
|
|
#define DLOAD_CINIT 3
|
|
|
|
struct dynamic_loader_allocate {
|
|
/* public: */
|
|
|
|
/*************************************************************************
|
|
* Function allocate
|
|
*
|
|
* Parameters:
|
|
* info A pointer to an information block for the section
|
|
* align The alignment of the storage in target AUs
|
|
*
|
|
* Effect:
|
|
* Allocates target memory for the specified section and fills in the
|
|
* load_addr and run_addr fields of the section info structure. Returns TRUE
|
|
* for success, FALSE for failure.
|
|
*
|
|
* Notes:
|
|
* Frequently load_addr and run_addr are the same, but if they are not
|
|
* load_addr is used with dynamic_loader_initialize, and run_addr is
|
|
* used for almost all relocations. This function should always initialize
|
|
* both fields.
|
|
************************************************************************ */
|
|
int (*dload_allocate) (struct dynamic_loader_allocate *thisptr,
|
|
struct ldr_section_info *info, unsigned align);
|
|
|
|
/*************************************************************************
|
|
* Function deallocate
|
|
*
|
|
* Parameters:
|
|
* info A pointer to an information block for the section
|
|
*
|
|
* Effect:
|
|
* Releases the target memory previously allocated.
|
|
*
|
|
* Notes:
|
|
* The content of the info->name field is undefined on call to this function.
|
|
************************************************************************ */
|
|
void (*dload_deallocate) (struct dynamic_loader_allocate *thisptr,
|
|
struct ldr_section_info *info);
|
|
|
|
}; /* class dynamic_loader_allocate */
|
|
|
|
/*****************************************************************************
|
|
*****************************************************************************
|
|
* A class used by the dynamic loader to load data into a target. This class
|
|
* provides the interface-specific functions needed to load data.
|
|
*****************************************************************************
|
|
**************************************************************************** */
|
|
|
|
struct dynamic_loader_initialize {
|
|
/* public: */
|
|
/*************************************************************************
|
|
* Function connect
|
|
*
|
|
* Parameters:
|
|
* none
|
|
*
|
|
* Effect:
|
|
* Connect to the initialization interface. Returns TRUE for success,
|
|
* FALSE for failure.
|
|
*
|
|
* Notes:
|
|
* This function is called prior to use of any other functions in
|
|
* this interface.
|
|
************************************************************************ */
|
|
int (*connect) (struct dynamic_loader_initialize *thisptr);
|
|
|
|
/*************************************************************************
|
|
* Function readmem
|
|
*
|
|
* Parameters:
|
|
* bufr Pointer to a word-aligned buffer for the result
|
|
* locn Target address of first data element
|
|
* info Section info for the section in which the address resides
|
|
* bytsiz Size of the data to be read in sizeof() units
|
|
*
|
|
* Effect:
|
|
* Fills the specified buffer with data from the target. Returns TRUE for
|
|
* success, FALSE for failure.
|
|
************************************************************************ */
|
|
int (*readmem) (struct dynamic_loader_initialize *thisptr,
|
|
void *bufr,
|
|
ldr_addr locn,
|
|
struct ldr_section_info *info, unsigned bytsiz);
|
|
|
|
/*************************************************************************
|
|
* Function writemem
|
|
*
|
|
* Parameters:
|
|
* bufr Pointer to a word-aligned buffer of data
|
|
* locn Target address of first data element to be written
|
|
* info Section info for the section in which the address resides
|
|
* bytsiz Size of the data to be written in sizeof() units
|
|
*
|
|
* Effect:
|
|
* Writes the specified buffer to the target. Returns TRUE for success,
|
|
* FALSE for failure.
|
|
************************************************************************ */
|
|
int (*writemem) (struct dynamic_loader_initialize *thisptr,
|
|
void *bufr,
|
|
ldr_addr locn,
|
|
struct ldr_section_info *info, unsigned bytsiz);
|
|
|
|
/*************************************************************************
|
|
* Function fillmem
|
|
*
|
|
* Parameters:
|
|
* locn Target address of first data element to be written
|
|
* info Section info for the section in which the address resides
|
|
* bytsiz Size of the data to be written in sizeof() units
|
|
* val Value to be written in each byte
|
|
* Effect:
|
|
* Fills the specified area of target memory. Returns TRUE for success,
|
|
* FALSE for failure.
|
|
************************************************************************ */
|
|
int (*fillmem) (struct dynamic_loader_initialize *thisptr,
|
|
ldr_addr locn, struct ldr_section_info *info,
|
|
unsigned bytsiz, unsigned val);
|
|
|
|
/*************************************************************************
|
|
* Function execute
|
|
*
|
|
* Parameters:
|
|
* start Starting address
|
|
*
|
|
* Effect:
|
|
* The target code at the specified starting address is executed.
|
|
*
|
|
* Notes:
|
|
* This function is called at the end of the dynamic load process
|
|
* if the input module has specified a starting address.
|
|
************************************************************************ */
|
|
int (*execute) (struct dynamic_loader_initialize *thisptr,
|
|
ldr_addr start);
|
|
|
|
/*************************************************************************
|
|
* Function release
|
|
*
|
|
* Parameters:
|
|
* none
|
|
*
|
|
* Effect:
|
|
* Releases the connection to the load interface.
|
|
*
|
|
* Notes:
|
|
* This function is called at the end of the dynamic load process.
|
|
************************************************************************ */
|
|
void (*release) (struct dynamic_loader_initialize *thisptr);
|
|
|
|
}; /* class dynamic_loader_initialize */
|
|
|
|
#endif /* _DYNAMIC_LOADER_H_ */
|