aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tidspbridge/include/dspbridge/dynamic_loader.h
blob: 052d27ee8b1a92edda362d2f2e874a229273cfa9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
/*
 * 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 */

/*****************************************************************************
 * 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_ */