1/*
2 *  Copyright 2001-2008 Texas Instruments - http://www.ti.com/
3 *
4 *  Licensed under the Apache License, Version 2.0 (the "License");
5 *  you may not use this file except in compliance with the License.
6 *  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *  Unless required by applicable law or agreed to in writing, software
11 *  distributed under the License is distributed on an "AS IS" BASIS,
12 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 *  See the License for the specific language governing permissions and
14 *  limitations under the License.
15 */
16
17
18
19#ifndef _DYNAMIC_LOADER_H_
20#define _DYNAMIC_LOADER_H_
21#include <stdarg.h>
22#ifndef __KERNEL__
23#include <stdint.h>
24#else
25#include <linux/types.h>
26#endif
27
28#ifdef __cplusplus
29extern "C" {			/* C-only version */
30#endif
31
32/* Optional optimization defines */
33#define OPT_ELIMINATE_EXTRA_DLOAD 1
34/* #define OPT_ZERO_COPY_LOADER 1 */
35
36
37/*
38 * Dynamic Loader
39 *
40 * The function of the dynamic loader is to load a "module" containing
41 * instructions
42 * for a "target" processor into that processor.  In the process it assigns
43 * memory
44 * for the module, resolves symbol references made by the module, and remembers
45 * symbols defined by the module.
46 *
47 * The dynamic loader is parameterized for a particular system by 4 classes
48 * that supply
49 * the module and system specific functions it requires
50 */
51	/* The read functions for the module image to be loaded */
52	struct Dynamic_Loader_Stream;
53	/*typedef struct Dynamic_Loader_Stream Dynamic_Loader_Stream;*/
54
55	/* This class defines "host" symbol and support functions */
56	struct Dynamic_Loader_Sym;
57	/*typedef struct Dynamic_Loader_Sym Dynamic_Loader_Sym;*/
58
59	/* This class defines the allocator for "target" memory */
60	struct Dynamic_Loader_Allocate;
61	/*typedef struct Dynamic_Loader_Allocate Dynamic_Loader_Allocate;*/
62
63	/* This class defines the copy-into-target-memory functions */
64	struct Dynamic_Loader_Initialize;
65	/*typedef struct Dynamic_Loader_Initialize Dynamic_Loader_Initialize;*/
66
67/*
68 * Option flags to modify the behavior of module loading
69 */
70#define DLOAD_INITBSS 0x1	/* initialize BSS sections to zero */
71#define DLOAD_BIGEND 0x2	/* require big-endian load module */
72#define DLOAD_LITTLE 0x4	/* require little-endian load module */
73
74	typedef void *DLOAD_mhandle;	/* module handle for loaded modules */
75
76/*****************************************************************************
77 * Procedure Dynamic_Load_Module
78 *
79 * Parameters:
80 *  module  The input stream that supplies the module image
81 *  syms    Host-side symbol table and malloc/free functions
82 *  alloc   Target-side memory allocation
83 *  init    Target-side memory initialization, or NULL for symbol read only
84 *  options Option flags DLOAD_*
85 *  mhandle A module handle for use with Dynamic_Unload
86 *
87 * Effect:
88 *  The module image is read using *module.  Target storage for the new image is
89 * obtained from *alloc.  Symbols defined and referenced by the module are
90 * managed using *syms.  The image is then relocated and references resolved
91 * as necessary, and the resulting executable bits are placed into target memory
92 * using *init.
93 *
94 * Returns:
95 *  On a successful load, a module handle is placed in *mhandle, and zero is
96 * returned.  On error, the number of errors detected is returned.  Individual
97 * errors are reported during the load process using syms->Error_Report().
98 *****************************************************************************/
99	extern int Dynamic_Load_Module(
100					/* the source for the module image*/
101					struct Dynamic_Loader_Stream * module,
102					   /* host support for symbols and storage*/
103				       struct Dynamic_Loader_Sym * syms,
104					   /* the target memory allocator*/
105				       struct Dynamic_Loader_Allocate * alloc,
106					   /* the target memory initializer*/
107				       struct Dynamic_Loader_Initialize * init,
108				       unsigned options,	/* option flags*/
109				       DLOAD_mhandle * mhandle	/* the returned module handle*/
110	    );
111
112#ifdef OPT_ELIMINATE_EXTRA_DLOAD
113/*****************************************************************************
114 * Procedure Dynamic_Open_Module
115 *
116 * Parameters:
117 *  module  The input stream that supplies the module image
118 *  syms    Host-side symbol table and malloc/free functions
119 *  alloc   Target-side memory allocation
120 *  init    Target-side memory initialization, or NULL for symbol read only
121 *  options Option flags DLOAD_*
122 *  mhandle A module handle for use with Dynamic_Unload
123 *
124 * Effect:
125 *  The module image is read using *module.  Target storage for the new image is
126 * obtained from *alloc.  Symbols defined and referenced by the module are
127 * managed using *syms.  The image is then relocated and references resolved
128 * as necessary, and the resulting executable bits are placed into target memory
129 * using *init.
130 *
131 * Returns:
132 *  On a successful load, a module handle is placed in *mhandle, and zero is
133 * returned.  On error, the number of errors detected is returned.  Individual
134 * errors are reported during the load process using syms->Error_Report().
135 *****************************************************************************/
136        extern int Dynamic_Open_Module(struct Dynamic_Loader_Stream * module,  // the source for the module image
137                                       struct Dynamic_Loader_Sym * syms,       // host support for symbols and storage
138                                       struct Dynamic_Loader_Allocate * alloc, // the target memory allocator
139                                       struct Dynamic_Loader_Initialize * init,        // the target memory initializer
140                                       unsigned options,        // option flags
141                                       DLOAD_mhandle * mhandle  // the returned module handle
142            );
143#endif
144
145/*****************************************************************************
146 * Procedure Dynamic_Unload_Module
147 *
148 * Parameters:
149 *  mhandle A module handle from Dynamic_Load_Module
150 *  syms    Host-side symbol table and malloc/free functions
151 *  alloc   Target-side memory allocation
152 *
153 * Effect:
154 *  The module specified by mhandle is unloaded.  Unloading causes all
155 * target memory to be deallocated, all symbols defined by the module to
156 * be purged, and any host-side storage used by the dynamic loader for
157 * this module to be released.
158 *
159 * Returns:
160 *  Zero for success. On error, the number of errors detected is returned.
161 * Individual errors are reported using syms->Error_Report().
162 *****************************************************************************/
163	extern int Dynamic_Unload_Module(DLOAD_mhandle mhandle,	/* the module
164															   handle*/
165					 /* host support for symbols and storage*/
166					 struct Dynamic_Loader_Sym * syms,
167					 /* the target memory allocator*/
168					 struct Dynamic_Loader_Allocate * alloc,
169					 /* the target memory initializer*/
170					 struct Dynamic_Loader_Initialize * init
171	    );
172
173/*****************************************************************************
174 *****************************************************************************
175 * A class used by the dynamic loader for input of the module image
176 *****************************************************************************
177 *****************************************************************************/
178	struct Dynamic_Loader_Stream {
179/* public: */
180    /*************************************************************************
181     * read_buffer
182     *
183     * PARAMETERS :
184     *  buffer  Pointer to the buffer to fill
185     *  bufsiz  Amount of data desired in sizeof() units
186     *
187     * EFFECT :
188     *  Reads the specified amount of data from the module input stream
189     * into the specified buffer.  Returns the amount of data read in sizeof()
190     * units (which if less than the specification, represents an error).
191     *
192     * NOTES:
193     *  In release 1 increments the file position by the number of bytes read
194     *
195     *************************************************************************/
196		int (*read_buffer) (struct Dynamic_Loader_Stream * thisptr,
197				    void *buffer, unsigned bufsiz);
198
199    /*************************************************************************
200     * set_file_posn (release 1 only)
201     *
202     * PARAMETERS :
203     *  posn  Desired file position relative to start of file in sizeof() units.
204     *
205     * EFFECT :
206     *  Adjusts the internal state of the stream object so that the next
207     * read_buffer call will begin to read at the specified offset from
208     * the beginning of the input module.  Returns 0 for success, non-zero
209     * for failure.
210     *
211     *************************************************************************/
212		int (*set_file_posn) (struct Dynamic_Loader_Stream * thisptr,
213					unsigned int posn);	/* to be eliminated in release 2*/
214
215	};
216
217/*****************************************************************************
218 *****************************************************************************
219 * A class used by the dynamic loader for symbol table support and
220 * miscellaneous host-side functions
221 *****************************************************************************
222 *****************************************************************************/
223#ifndef __KERNEL__
224	typedef uint32_t LDR_ADDR;
225#else
226	typedef u32 LDR_ADDR;
227#endif
228
229/*
230 * the structure of a symbol known to the dynamic loader
231 */
232	struct dynload_symbol {
233		LDR_ADDR value;
234	} ;
235
236	struct Dynamic_Loader_Sym {
237/* public: */
238    /*************************************************************************
239     * Find_Matching_Symbol
240     *
241     * PARAMETERS :
242     *  name    The name of the desired symbol
243     *
244     * EFFECT :
245     *  Locates a symbol matching the name specified.  A pointer to the
246     * symbol is returned if it exists; 0 is returned if no such symbol is
247     * found.
248     *
249     *************************************************************************/
250		struct dynload_symbol *(*Find_Matching_Symbol)
251			(struct Dynamic_Loader_Sym *
252							 thisptr,
253							 const char *name);
254
255    /*************************************************************************
256     * Add_To_Symbol_Table
257     *
258     * PARAMETERS :
259     *  nname       Pointer to the name of the new symbol
260     *  moduleid    An opaque module id assigned by the dynamic loader
261     *
262     * EFFECT :
263     *  The new symbol is added to the table.  A pointer to the symbol is
264     * returned, or NULL is returned for failure.
265     *
266     * NOTES:
267     *  It is permissible for this function to return NULL; the effect is that
268     * the named symbol will not be available to resolve references in
269     * subsequent loads.  Returning NULL will not cause the current load
270     * to fail.
271     *************************************************************************/
272		struct dynload_symbol *(*Add_To_Symbol_Table)
273						(struct Dynamic_Loader_Sym *
274							thisptr,
275							const char *nname,
276							unsigned moduleid);
277
278    /*************************************************************************
279     * Purge_Symbol_Table
280     *
281     * PARAMETERS :
282     *  moduleid    An opaque module id assigned by the dynamic loader
283     *
284     * EFFECT :
285     *  Each symbol in the symbol table whose moduleid matches the argument
286     * is removed from the table.
287     *************************************************************************/
288		void (*Purge_Symbol_Table) (struct Dynamic_Loader_Sym * thisptr,
289					    unsigned moduleid);
290
291    /*************************************************************************
292     * Allocate
293     *
294     * PARAMETERS :
295     *  memsiz  size of desired memory in sizeof() units
296     *
297     * EFFECT :
298     *  Returns a pointer to some "host" memory for use by the dynamic
299     * loader, or NULL for failure.
300     * This function is serves as a replaceable form of "malloc" to
301     * allow the user to configure the memory usage of the dynamic loader.
302     *************************************************************************/
303		void *(*Allocate) (struct Dynamic_Loader_Sym * thisptr,
304				   unsigned memsiz);
305
306    /*************************************************************************
307     * Deallocate
308     *
309     * PARAMETERS :
310     *  memptr  pointer to previously allocated memory
311     *
312     * EFFECT :
313     *  Releases the previously allocated "host" memory.
314     *************************************************************************/
315		void (*Deallocate) (struct Dynamic_Loader_Sym * thisptr, void *memptr);
316
317    /*************************************************************************
318     * Error_Report
319     *
320     * PARAMETERS :
321     *  errstr  pointer to an error string
322     *  args    additional arguments
323     *
324     * EFFECT :
325     *  This function provides an error reporting interface for the dynamic
326     * loader.  The error string and arguments are designed as for the
327     * library function vprintf.
328     *************************************************************************/
329		void (*Error_Report) (struct Dynamic_Loader_Sym * thisptr,
330				      const char *errstr, va_list args);
331
332	};			/* class Dynamic_Loader_Sym */
333
334/*****************************************************************************
335 *****************************************************************************
336 * A class used by the dynamic loader to allocate and deallocate target memory.
337 *****************************************************************************
338 *****************************************************************************/
339
340	struct LDR_SECTION_INFO {
341		/* Name of the memory section assigned at build time */
342		const char *name;
343		LDR_ADDR run_addr;	/* execution address of the section */
344		LDR_ADDR load_addr;	/* load address of the section */
345		LDR_ADDR size;	/* size of the section in addressable units */
346/* #ifndef _BIG_ENDIAN *//* _BIG_ENDIAN Not defined by bridge driver */
347#ifdef __KERNEL__
348		u16 page;	/* memory page or view */
349		u16 type;	/* one of the section types below */
350#else
351		uint16_t page;	/* memory page or view */
352		uint16_t type;	/* one of the section types below */
353#endif
354/*#else
355#ifdef __KERNEL__
356		u16 type;*/	/* one of the section types below */
357/*		u16 page;*/	/* memory page or view */
358/*#else
359		uint16_t type;*//* one of the section types below */
360/*		uint16_t page;*//* memory page or view */
361/*#endif
362#endif*//* _BIG_ENDIAN Not defined by bridge driver */
363		/* a context field for use by Dynamic_Loader_Allocate;
364					   ignored but maintained by the dynamic loader */
365#ifdef __KERNEL__
366		u32 context;
367#else
368		uintptr_t context;
369#endif
370	} ;
371
372/* use this macro to extract type of section from LDR_SECTION_INFO.type field */
373#define DLOAD_SECTION_TYPE(typeinfo) (typeinfo & 0xF)
374
375/* type of section to be allocated */
376#define DLOAD_TEXT 0
377#define DLOAD_DATA 1
378#define DLOAD_BSS 2
379	/* internal use only, run-time cinit will be of type DLOAD_DATA */
380#define DLOAD_CINIT 3
381
382	struct Dynamic_Loader_Allocate {
383/* public: */
384
385    /*************************************************************************
386    * Function allocate
387    *
388    * Parameters:
389    *   info        A pointer to an information block for the section
390    *   align       The alignment of the storage in target AUs
391    *
392    * Effect:
393    *   Allocates target memory for the specified section and fills in the
394    * load_addr and run_addr fields of the section info structure. Returns TRUE
395    * for success, FALSE for failure.
396    *
397    * Notes:
398    *   Frequently load_addr and run_addr are the same, but if they are not
399    * load_addr is used with Dynamic_Loader_Initialize, and run_addr is
400    * used for almost all relocations.  This function should always initialize
401    * both fields.
402    *************************************************************************/
403		int (*Allocate) (struct Dynamic_Loader_Allocate * thisptr,
404				 struct LDR_SECTION_INFO * info, unsigned align);
405
406    /*************************************************************************
407    * Function deallocate
408    *
409    * Parameters:
410    *   info        A pointer to an information block for the section
411    *
412    * Effect:
413    *   Releases the target memory previously allocated.
414    *
415    * Notes:
416    * The content of the info->name field is undefined on call to this function.
417    *************************************************************************/
418		void (*Deallocate) (struct Dynamic_Loader_Allocate * thisptr,
419				    struct LDR_SECTION_INFO * info);
420
421	};			/* class Dynamic_Loader_Allocate */
422
423/*****************************************************************************
424 *****************************************************************************
425 * A class used by the dynamic loader to load data into a target.  This class
426 * provides the interface-specific functions needed to load data.
427 *****************************************************************************
428 *****************************************************************************/
429
430	struct Dynamic_Loader_Initialize {
431/* public: */
432    /*************************************************************************
433    * Function connect
434    *
435    * Parameters:
436    *   none
437    *
438    * Effect:
439    *   Connect to the initialization interface. Returns TRUE for success,
440    * FALSE for failure.
441    *
442    * Notes:
443    *   This function is called prior to use of any other functions in
444    * this interface.
445    *************************************************************************/
446		int (*connect) (struct Dynamic_Loader_Initialize * thisptr);
447
448    /*************************************************************************
449    * Function readmem
450    *
451    * Parameters:
452    *   bufr        Pointer to a word-aligned buffer for the result
453    *   locn        Target address of first data element
454    *   info        Section info for the section in which the address resides
455    *   bytsiz      Size of the data to be read in sizeof() units
456    *
457    * Effect:
458    *   Fills the specified buffer with data from the target.  Returns TRUE for
459    * success, FALSE for failure.
460    *************************************************************************/
461		int (*readmem) (struct Dynamic_Loader_Initialize * thisptr, void *bufr,
462				LDR_ADDR locn, struct LDR_SECTION_INFO * info,
463				unsigned bytsiz);
464
465    /*************************************************************************
466    * Function writemem
467    *
468    * Parameters:
469    *   bufr        Pointer to a word-aligned buffer of data
470    *   locn        Target address of first data element to be written
471    *   info        Section info for the section in which the address resides
472    *   bytsiz      Size of the data to be written in sizeof() units
473    *
474    * Effect:
475    *   Writes the specified buffer to the target.  Returns TRUE for success,
476    * FALSE for failure.
477    *************************************************************************/
478		int (*writemem) (struct Dynamic_Loader_Initialize * thisptr,
479				 void *bufr, LDR_ADDR locn,
480				 struct LDR_SECTION_INFO * info, unsigned bytsiz);
481
482    /*************************************************************************
483    * Function fillmem
484    *
485    * Parameters:
486    *   locn        Target address of first data element to be written
487    *   info        Section info for the section in which the address resides
488    *   bytsiz      Size of the data to be written in sizeof() units
489    *   val         Value to be written in each byte
490    * Effect:
491    *   Fills the specified area of target memory.  Returns TRUE for success,
492    * FALSE for failure.
493    *************************************************************************/
494		int (*fillmem) (struct Dynamic_Loader_Initialize * thisptr,
495				LDR_ADDR locn, struct LDR_SECTION_INFO * info,
496				unsigned bytsiz, unsigned val);
497
498    /*************************************************************************
499    * Function execute
500    *
501    * Parameters:
502    *   start       Starting address
503    *
504    * Effect:
505    *   The target code at the specified starting address is executed.
506    *
507    * Notes:
508    *   This function is called at the end of the dynamic load process
509    * if the input module has specified a starting address.
510    *************************************************************************/
511		int (*execute) (struct Dynamic_Loader_Initialize * thisptr,
512				LDR_ADDR start);
513
514    /*************************************************************************
515    * Function release
516    *
517    * Parameters:
518    *   none
519    *
520    * Effect:
521    *   Releases the connection to the load interface.
522    *
523    * Notes:
524    *   This function is called at the end of the dynamic load process.
525    *************************************************************************/
526		void (*release) (struct Dynamic_Loader_Initialize * thisptr);
527
528	};			/* class Dynamic_Loader_Initialize */
529#ifdef __cplusplus
530}
531#endif
532#endif				/* _DYNAMIC_LOADER_H_ */
533
534