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