Update from omapzoom 18-Aug-2008
[bridge-dev.git] / 0003-TI-DSP-BRIDGE-Doff-image-dynamic-loader.patch
blob0d07f8697663b64a7f4f89d1f5015de265b69a43
1 From 1512b1657fc0c7b9f948f8c3a3dec79230f45fe8 Mon Sep 17 00:00:00 2001
2 From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
3 Date: Fri, 15 Aug 2008 01:55:54 +0300
4 Subject: [PATCH 03/10] TI DSP BRIDGE: Doff image dynamic loader
6 Initial port from omapzoom
7 http://omapzoom.org/gf/project/omapbridge
9 For details,
10 http://omapzoom.org/gf/project/omapbridge/docman/?subdir=3
12 Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
13 ---
14 drivers/dsp/bridge/dynload/cload.c | 1856 ++++++++++++++++++++++++
15 drivers/dsp/bridge/dynload/dlclasses_hdr.h | 41 +
16 drivers/dsp/bridge/dynload/dload_internal.h | 237 +++
17 drivers/dsp/bridge/dynload/doff.h | 347 +++++
18 drivers/dsp/bridge/dynload/getsection.c | 412 ++++++
19 drivers/dsp/bridge/dynload/header.h | 59 +
20 drivers/dsp/bridge/dynload/module_list.h | 161 ++
21 drivers/dsp/bridge/dynload/params.h | 231 +++
22 drivers/dsp/bridge/dynload/reloc.c | 425 ++++++
23 drivers/dsp/bridge/dynload/reloc_table.h | 102 ++
24 drivers/dsp/bridge/dynload/reloc_table_c6000.c | 258 ++++
25 11 files changed, 4129 insertions(+), 0 deletions(-)
26 create mode 100644 drivers/dsp/bridge/dynload/cload.c
27 create mode 100644 drivers/dsp/bridge/dynload/dlclasses_hdr.h
28 create mode 100644 drivers/dsp/bridge/dynload/dload_internal.h
29 create mode 100644 drivers/dsp/bridge/dynload/doff.h
30 create mode 100644 drivers/dsp/bridge/dynload/getsection.c
31 create mode 100644 drivers/dsp/bridge/dynload/header.h
32 create mode 100644 drivers/dsp/bridge/dynload/module_list.h
33 create mode 100644 drivers/dsp/bridge/dynload/params.h
34 create mode 100644 drivers/dsp/bridge/dynload/reloc.c
35 create mode 100644 drivers/dsp/bridge/dynload/reloc_table.h
36 create mode 100644 drivers/dsp/bridge/dynload/reloc_table_c6000.c
38 Index: lk/drivers/dsp/bridge/dynload/cload.c
39 ===================================================================
40 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
41 +++ lk/drivers/dsp/bridge/dynload/cload.c 2008-08-18 10:38:35.000000000 +0300
42 @@ -0,0 +1,1856 @@
43 +/*
44 + * linux/drivers/dsp/bridge/dynload/cload.c
45 + *
46 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
47 + *
48 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
49 + *
50 + * This package is free software; you can redistribute it and/or modify
51 + * it under the terms of the GNU General Public License version 2 as
52 + * published by the Free Software Foundation.
53 + *
54 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
55 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
56 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
57 + */
59 +#include "header.h"
61 +#include "module_list.h"
62 +#define LINKER_MODULES_HEADER ("_" MODULES_HEADER)
64 +/*
65 + * we use the fact that DOFF section records are shaped just like
66 + * LDR_SECTION_INFO to reduce our section storage usage. This macro marks
67 + * the places where that assumption is made
68 + */
69 +#define DOFFSEC_IS_LDRSEC(pdoffsec) ((struct LDR_SECTION_INFO *)(pdoffsec))
71 +/*
72 + * forward references
73 + */
74 +static void dload_symbols(struct dload_state *dlthis);
75 +static void dload_data(struct dload_state *dlthis);
76 +static void allocate_sections(struct dload_state *dlthis);
77 +static void string_table_free(struct dload_state *dlthis);
78 +static void symbol_table_free(struct dload_state *dlthis);
79 +static void section_table_free(struct dload_state *dlthis);
80 +static void init_module_handle(struct dload_state *dlthis);
81 +#if BITS_PER_AU > BITS_PER_BYTE
82 +static char *unpack_name(struct dload_state *dlthis, u32 soffset);
83 +#endif
85 +static const char CINITNAME[] = { ".cinit" };
86 +static const char LOADER_DLLVIEW_ROOT[] = { "?DLModules?" };
88 +/*
89 + * Error strings
90 + */
91 +static const char E_READSTRM[] = { "Error reading %s from input stream" };
92 +static const char E_ALLOC[] = { "Syms->Allocate( %d ) failed" };
93 +static const char E_TGTALLOC[] =
94 + { "Target memory allocate failed, section %s size " FMT_UI32 };
95 +static const char E_INITFAIL[] = { "%s to target address " FMT_UI32 " failed" };
96 +static const char E_DLVWRITE[] = { "Write to DLLview list failed" };
97 +static const char E_ICONNECT[] = { "Connect call to init interface failed" };
98 +static const char E_CHECKSUM[] = { "Checksum failed on %s" };
100 +/*************************************************************************
101 + * Procedure dload_error
103 + * Parameters:
104 + * errtxt description of the error, printf style
105 + * ... additional information
107 + * Effect:
108 + * Reports or records the error as appropriate.
109 + ************************************************************************/
110 +void dload_error(struct dload_state *dlthis, const char *errtxt, ...)
112 + va_list args;
114 + va_start(args, errtxt);
115 + dlthis->mysym->Error_Report(dlthis->mysym, errtxt, args);
116 + va_end(args);
117 + dlthis->dload_errcount += 1;
119 +} /* dload_error */
121 +#define DL_ERROR(zza, zzb) dload_error(dlthis, zza, zzb)
123 +/*************************************************************************
124 + * Procedure dload_syms_error
126 + * Parameters:
127 + * errtxt description of the error, printf style
128 + * ... additional information
130 + * Effect:
131 + * Reports or records the error as appropriate.
132 + ************************************************************************/
133 +void dload_syms_error(struct Dynamic_Loader_Sym *syms, const char *errtxt, ...)
135 + va_list args;
137 + va_start(args, errtxt);
138 + syms->Error_Report(syms, errtxt, args);
139 + va_end(args);
142 +/*************************************************************************
143 + * Procedure Dynamic_Load_Module
145 + * Parameters:
146 + * module The input stream that supplies the module image
147 + * syms Host-side symbol table and malloc/free functions
148 + * alloc Target-side memory allocation
149 + * init Target-side memory initialization
150 + * options Option flags DLOAD_*
151 + * mhandle A module handle for use with Dynamic_Unload
153 + * Effect:
154 + * The module image is read using *module. Target storage for the new
155 + * image is
156 + * obtained from *alloc. Symbols defined and referenced by the module are
157 + * managed using *syms. The image is then relocated and references
158 + * resolved as necessary, and the resulting executable bits are placed
159 + * into target memory using *init.
161 + * Returns:
162 + * On a successful load, a module handle is placed in *mhandle,
163 + * and zero is returned. On error, the number of errors detected is
164 + * returned. Individual errors are reported during the load process
165 + * using syms->Error_Report().
166 + ***********************************************************************/
167 +extern int Dynamic_Load_Module(struct Dynamic_Loader_Stream *module,
168 + struct Dynamic_Loader_Sym *syms ,
169 + struct Dynamic_Loader_Allocate *alloc,
170 + struct Dynamic_Loader_Initialize *init,
171 + unsigned options, DLOAD_mhandle *mhandle)
173 + register unsigned *dp, sz;
174 + struct dload_state dl_state; /* internal state for this call */
176 + /* blast our internal state */
177 + dp = (unsigned *)&dl_state;
178 + for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1)
179 + *dp++ = 0;
181 + /* Enable _only_ BSS initialization if enabled by user */
182 + if ((options & DLOAD_INITBSS) == DLOAD_INITBSS)
183 + dl_state.myoptions = DLOAD_INITBSS;
185 + /* Check that mandatory arguments are present */
186 + if (!module || !syms) {
187 + dload_error(&dl_state, "Required parameter is NULL");
188 + } else {
189 + dl_state.strm = module;
190 + dl_state.mysym = syms;
191 + dload_headers(&dl_state);
192 + if (!dl_state.dload_errcount)
193 + dload_strings(&dl_state, false);
194 + if (!dl_state.dload_errcount)
195 + dload_sections(&dl_state);
197 + if (init && !dl_state.dload_errcount) {
198 + if (init->connect(init)) {
199 + dl_state.myio = init;
200 + dl_state.myalloc = alloc;
201 + /* do now, before reducing symbols */
202 + allocate_sections(&dl_state);
203 + } else
204 + dload_error(&dl_state, E_ICONNECT);
207 + if (!dl_state.dload_errcount) {
208 + /* fix up entry point address */
209 + unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1;
210 + if (sref < dl_state.allocated_secn_count)
211 + dl_state.dfile_hdr.df_entrypt +=
212 + dl_state.ldr_sections[sref].run_addr;
214 + dload_symbols(&dl_state);
217 + if (init && !dl_state.dload_errcount)
218 + dload_data(&dl_state);
220 + init_module_handle(&dl_state);
222 + if (dl_state.myio) {
223 + if ((!dl_state.dload_errcount) &&
224 + (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF)) {
225 + if (init != NULL) {
226 + if (!init->execute(init,
227 + dl_state.dfile_hdr.df_entrypt))
228 + dload_error(&dl_state,
229 + "Init->Execute Failed");
230 + } else {
231 + dload_error(&dl_state, "init is NULL");
234 + init->release(init);
237 + symbol_table_free(&dl_state);
238 + section_table_free(&dl_state);
239 + string_table_free(&dl_state);
241 + if (dl_state.dload_errcount) {
242 + Dynamic_Unload_Module(dl_state.myhandle, syms, alloc,
243 + init);
244 + dl_state.myhandle = NULL;
248 + if (mhandle)
249 + *mhandle = dl_state.myhandle; /* give back the handle */
251 + return dl_state.dload_errcount;
252 +} /* DLOAD_File */
254 +/*************************************************************************
255 + * Procedure Dynamic_Open_Module
257 + * Parameters:
258 + * module The input stream that supplies the module image
259 + * syms Host-side symbol table and malloc/free functions
260 + * alloc Target-side memory allocation
261 + * init Target-side memory initialization
262 + * options Option flags DLOAD_*
263 + * mhandle A module handle for use with Dynamic_Unload
265 + * Effect:
266 + * The module image is read using *module. Target storage for the new
267 + * image is
268 + * obtained from *alloc. Symbols defined and referenced by the module are
269 + * managed using *syms. The image is then relocated and references
270 + * resolved as necessary, and the resulting executable bits are placed
271 + * into target memory using *init.
273 + * Returns:
274 + * On a successful load, a module handle is placed in *mhandle,
275 + * and zero is returned. On error, the number of errors detected is
276 + * returned. Individual errors are reported during the load process
277 + * using syms->Error_Report().
278 + ***********************************************************************/
279 +extern int
280 +Dynamic_Open_Module(struct Dynamic_Loader_Stream *module,
281 + struct Dynamic_Loader_Sym *syms,
282 + struct Dynamic_Loader_Allocate *alloc,
283 + struct Dynamic_Loader_Initialize *init,
284 + unsigned options, DLOAD_mhandle *mhandle)
286 + register unsigned *dp, sz;
287 + struct dload_state dl_state; /* internal state for this call */
289 + /* blast our internal state */
290 + dp = (unsigned *)&dl_state;
291 + for (sz = sizeof(dl_state) / sizeof(unsigned); sz > 0; sz -= 1)
292 + *dp++ = 0;
294 + /* Enable _only_ BSS initialization if enabled by user */
295 + if ((options & DLOAD_INITBSS) == DLOAD_INITBSS)
296 + dl_state.myoptions = DLOAD_INITBSS;
298 + /* Check that mandatory arguments are present */
299 + if (!module || !syms) {
300 + dload_error(&dl_state, "Required parameter is NULL");
301 + } else {
302 + dl_state.strm = module;
303 + dl_state.mysym = syms;
304 + dload_headers(&dl_state);
305 + if (!dl_state.dload_errcount)
306 + dload_strings(&dl_state, false);
307 + if (!dl_state.dload_errcount)
308 + dload_sections(&dl_state);
310 + if (init && !dl_state.dload_errcount) {
311 + if (init->connect(init)) {
312 + dl_state.myio = init;
313 + dl_state.myalloc = alloc;
314 + /* do now, before reducing symbols */
315 + allocate_sections(&dl_state);
316 + } else
317 + dload_error(&dl_state, E_ICONNECT);
320 + if (!dl_state.dload_errcount) {
321 + /* fix up entry point address */
322 + unsigned sref = dl_state.dfile_hdr.df_entry_secn - 1;
323 + if (sref < dl_state.allocated_secn_count)
324 + dl_state.dfile_hdr.df_entrypt +=
325 + dl_state.ldr_sections[sref].run_addr;
327 + dload_symbols(&dl_state);
330 + init_module_handle(&dl_state);
332 + if (dl_state.myio) {
333 + if ((!dl_state.dload_errcount)
334 + && (dl_state.dfile_hdr.df_entry_secn != DN_UNDEF))
335 + if (!init->execute(init,
336 + dl_state.dfile_hdr.df_entrypt))
337 + dload_error(&dl_state,
338 + "Init->Execute Failed");
339 + init->release(init);
342 + symbol_table_free(&dl_state);
343 + section_table_free(&dl_state);
344 + string_table_free(&dl_state);
346 + if (dl_state.dload_errcount) {
347 + Dynamic_Unload_Module(dl_state.myhandle, syms, alloc,
348 + init);
349 + dl_state.myhandle = NULL;
353 + if (mhandle)
354 + *mhandle = dl_state.myhandle; /* give back the handle */
356 + return dl_state.dload_errcount;
357 +} /* DLOAD_File */
359 +/*************************************************************************
360 + * Procedure dload_headers
362 + * Parameters:
363 + * none
365 + * Effect:
366 + * Loads the DOFF header and verify record. Deals with any byte-order
367 + * issues and checks them for validity.
368 + ************************************************************************/
369 +#define COMBINED_HEADER_SIZE (sizeof(struct doff_filehdr_t)+ \
370 + sizeof(struct doff_verify_rec_t))
372 +void dload_headers(struct dload_state *dlthis)
374 + u32 map;
376 + /* Read the header and the verify record as one. If we don't get it
377 + all, we're done */
378 + if (dlthis->strm->read_buffer(dlthis->strm, &dlthis->dfile_hdr,
379 + COMBINED_HEADER_SIZE) != COMBINED_HEADER_SIZE) {
380 + DL_ERROR(E_READSTRM, "File Headers");
381 + return;
383 + /*
384 + * Verify that we have the byte order of the file correct.
385 + * If not, must fix it before we can continue
386 + */
387 + map = REORDER_MAP(dlthis->dfile_hdr.df_byte_reshuffle);
388 + if (map != REORDER_MAP(BYTE_RESHUFFLE_VALUE)) {
389 + /* input is either byte-shuffled or bad */
390 + if ((map & 0xFCFCFCFC) == 0) { /* no obviously bogus bits */
391 + dload_reorder(&dlthis->dfile_hdr, COMBINED_HEADER_SIZE,
392 + map);
394 + if (dlthis->dfile_hdr.df_byte_reshuffle !=
395 + BYTE_RESHUFFLE_VALUE) {
396 + /* didn't fix the problem, the byte swap map is bad */
397 + dload_error(dlthis,
398 + "Bad byte swap map " FMT_UI32 " in header",
399 + dlthis->dfile_hdr.df_byte_reshuffle);
400 + return;
402 + dlthis->reorder_map = map; /* keep map for future use */
405 + /*
406 + * Verify checksum of header and verify record
407 + */
408 + if (~dload_checksum(&dlthis->dfile_hdr,
409 + sizeof(struct doff_filehdr_t)) ||
410 + ~dload_checksum(&dlthis->verify,
411 + sizeof(struct doff_verify_rec_t))) {
412 + DL_ERROR(E_CHECKSUM, "header or verify record");
413 + return;
415 +#if HOST_ENDIANNESS
416 + dlthis->dfile_hdr.df_byte_reshuffle = map; /* put back for later */
417 +#endif
419 + /* Check for valid target ID */
420 + if ((dlthis->dfile_hdr.df_target_id != TARGET_ID) &&
421 + -(dlthis->dfile_hdr.df_target_id != TMS470_ID)) {
422 + dload_error(dlthis, "Bad target ID 0x%x and TARGET_ID 0x%x",
423 + dlthis->dfile_hdr.df_target_id, TARGET_ID);
424 + return;
426 + /* Check for valid file format */
427 + if ((dlthis->dfile_hdr.df_doff_version != DOFF0)) {
428 + dload_error(dlthis, "Bad DOFF version 0x%x",
429 + dlthis->dfile_hdr.df_doff_version);
430 + return;
433 + /*
434 + * Apply reasonableness checks to count fields
435 + */
436 + if (dlthis->dfile_hdr.df_strtab_size > MAX_REASONABLE_STRINGTAB) {
437 + dload_error(dlthis, "Excessive string table size " FMT_UI32,
438 + dlthis->dfile_hdr.df_strtab_size);
439 + return;
441 + if (dlthis->dfile_hdr.df_no_scns > MAX_REASONABLE_SECTIONS) {
442 + dload_error(dlthis, "Excessive section count 0x%x",
443 + dlthis->dfile_hdr.df_no_scns);
444 + return;
446 +#ifndef TARGET_ENDIANNESS
447 + /*
448 + * Check that endianness does not disagree with explicit specification
449 + */
450 + if ((dlthis->dfile_hdr.df_flags >> ALIGN_COFF_ENDIANNESS) &
451 + dlthis->myoptions & ENDIANNESS_MASK) {
452 + dload_error(dlthis,
453 + "Input endianness disagrees with specified option");
454 + return;
456 + dlthis->big_e_target = dlthis->dfile_hdr.df_flags & DF_BIG;
457 +#endif
459 +} /* dload_headers */
461 +/* COFF Section Processing
463 + * COFF sections are read in and retained intact. Each record is embedded
464 + * in a new structure that records the updated load and
465 + * run addresses of the section */
467 +static const char SECN_ERRID[] = { "section" };
469 +/*************************************************************************
470 + * Procedure dload_sections
472 + * Parameters:
473 + * none
475 + * Effect:
476 + * Loads the section records into an internal table.
477 + ************************************************************************/
478 +void
479 +dload_sections(struct dload_state *dlthis)
481 + s16 siz;
482 + struct doff_scnhdr_t *shp;
483 + unsigned nsecs = dlthis->dfile_hdr.df_no_scns;
485 + /* allocate space for the DOFF section records */
486 + siz = nsecs * sizeof(struct doff_scnhdr_t);
487 + shp = (struct doff_scnhdr_t *)dlthis->mysym->Allocate(dlthis->mysym,
488 + siz);
489 + if (!shp) { /* not enough storage */
490 + DL_ERROR(E_ALLOC, siz);
491 + return;
493 + dlthis->sect_hdrs = shp;
495 + /* read in the section records */
496 + if (dlthis->strm->read_buffer(dlthis->strm, shp, siz) != siz) {
497 + DL_ERROR(E_READSTRM, SECN_ERRID);
498 + return;
501 + /* if we need to fix up byte order, do it now */
502 + if (dlthis->reorder_map)
503 + dload_reorder(shp, siz, dlthis->reorder_map);
505 + /* check for validity */
506 + if (~dload_checksum(dlthis->sect_hdrs, siz) !=
507 + dlthis->verify.dv_scn_rec_checksum) {
508 + DL_ERROR(E_CHECKSUM, SECN_ERRID);
509 + return;
512 +} /* dload_sections */
514 +/*****************************************************************************
515 + * Procedure allocate_sections
517 + * Parameters:
518 + * alloc target memory allocator class
520 + * Effect:
521 + * Assigns new (target) addresses for sections
522 + *****************************************************************************/
523 +static void allocate_sections(struct dload_state *dlthis)
525 + u16 curr_sect, nsecs, siz;
526 + struct doff_scnhdr_t *shp;
527 + struct LDR_SECTION_INFO *asecs;
528 + struct my_handle *hndl;
529 + nsecs = dlthis->dfile_hdr.df_no_scns;
530 + if (!nsecs)
531 + return;
532 + if ((dlthis->myalloc == NULL) &&
533 + (dlthis->dfile_hdr.df_target_scns > 0)) {
534 + DL_ERROR("Arg 3 (alloc) required but NULL", 0);
535 + return;
537 + /* allocate space for the module handle, which we will
538 + * keep for unload purposes */
539 + siz = dlthis->dfile_hdr.df_target_scns *
540 + sizeof(struct LDR_SECTION_INFO) + MY_HANDLE_SIZE;
541 + hndl = (struct my_handle *)dlthis->mysym->Allocate(dlthis->mysym, siz);
542 + if (!hndl) { /* not enough storage */
543 + DL_ERROR(E_ALLOC, siz);
544 + return;
546 + /* initialize the handle header */
547 + hndl->dm.hnext = hndl->dm.hprev = hndl; /* circular list */
548 + hndl->dm.hroot = 0;
549 + hndl->dm.dbthis = 0;
550 + dlthis->myhandle = hndl; /* save away for return */
551 + /* pointer to the section list of allocated sections */
552 + dlthis->ldr_sections = asecs = hndl->secns;
553 + /* * Insert names into all sections, make copies of
554 + the sections we allocate */
555 + shp = dlthis->sect_hdrs;
556 + for (curr_sect = 0; curr_sect < nsecs; curr_sect++) {
557 + u32 soffset = shp->ds_offset;
558 +#if BITS_PER_AU <= BITS_PER_BYTE
559 + /* attempt to insert the name of this section */
560 + if (soffset < dlthis->dfile_hdr.df_strtab_size)
561 + DOFFSEC_IS_LDRSEC(shp)->name = dlthis->str_head +
562 + soffset;
563 + else {
564 + dload_error(dlthis, "Bad name offset in section %d",
565 + curr_sect);
566 + DOFFSEC_IS_LDRSEC(shp)->name = NULL;
568 +#endif
569 + /* allocate target storage for sections that require it */
570 + if (DS_NEEDS_ALLOCATION(shp)) {
571 + *asecs = *DOFFSEC_IS_LDRSEC(shp);
572 + asecs->context = 0; /* zero the context field */
573 +#if BITS_PER_AU > BITS_PER_BYTE
574 + asecs->name = unpack_name(dlthis, soffset);
575 + dlthis->debug_string_size = soffset + dlthis->temp_len;
576 +#else
577 + dlthis->debug_string_size = soffset;
578 +#endif
579 + if (dlthis->myalloc != NULL) {
580 + if (!dlthis->myalloc->Allocate(dlthis->myalloc, asecs,
581 + DS_ALIGNMENT(asecs->type))) {
582 + dload_error(dlthis, E_TGTALLOC, asecs->name,
583 + asecs->size);
584 + return;
587 + /* keep address deltas in original section table */
588 + shp->ds_vaddr = asecs->load_addr - shp->ds_vaddr;
589 + shp->ds_paddr = asecs->run_addr - shp->ds_paddr;
590 + dlthis->allocated_secn_count += 1;
591 + } /* allocate target storage */
592 + shp += 1;
593 + asecs += 1;
595 +#if BITS_PER_AU <= BITS_PER_BYTE
596 + dlthis->debug_string_size +=
597 + strlen(dlthis->str_head + dlthis->debug_string_size) + 1;
598 +#endif
599 +} /* allocate sections */
601 +/*************************************************************************
602 + * Procedure section_table_free
604 + * Parameters:
605 + * none
607 + * Effect:
608 + * Frees any state used by the symbol table.
610 + * WARNING:
611 + * This routine is not allowed to declare errors!
612 + ************************************************************************/
613 +static void section_table_free(struct dload_state *dlthis)
615 + struct doff_scnhdr_t *shp;
617 + shp = dlthis->sect_hdrs;
618 + if (shp)
619 + dlthis->mysym->Deallocate(dlthis->mysym, shp);
621 +} /* section_table_free */
623 +/*************************************************************************
624 + * Procedure dload_strings
626 + * Parameters:
627 + * sec_names_only If true only read in the "section names"
628 + * portion of the string table
630 + * Effect:
631 + * Loads the DOFF string table into memory. DOFF keeps all strings in a
632 + * big unsorted array. We just read that array into memory in bulk.
633 + ************************************************************************/
634 +static const char S_STRINGTBL[] = { "string table" };
635 +void dload_strings(struct dload_state *dlthis, boolean sec_names_only)
637 + u32 ssiz;
638 + char *strbuf;
640 + if (sec_names_only) {
641 + ssiz = BYTE_TO_HOST(DOFF_ALIGN
642 + (dlthis->dfile_hdr.df_scn_name_size));
643 + } else {
644 + ssiz = BYTE_TO_HOST(DOFF_ALIGN
645 + (dlthis->dfile_hdr.df_strtab_size));
647 + if (ssiz == 0)
648 + return;
650 + /* get some memory for the string table */
651 +#if BITS_PER_AU > BITS_PER_BYTE
652 + strbuf = (char *)dlthis->mysym->Allocate(dlthis->mysym, ssiz +
653 + dlthis->dfile_hdr.df_max_str_len);
654 +#else
655 + strbuf = (char *)dlthis->mysym->Allocate(dlthis->mysym, ssiz);
656 +#endif
657 + if (strbuf == NULL) {
658 + DL_ERROR(E_ALLOC, ssiz);
659 + return;
661 + dlthis->str_head = strbuf;
662 +#if BITS_PER_AU > BITS_PER_BYTE
663 + dlthis->str_temp = strbuf + ssiz;
664 +#endif
665 + /* read in the strings and verify them */
666 + if ((unsigned)(dlthis->strm->read_buffer(dlthis->strm, strbuf,
667 + ssiz)) != ssiz) {
668 + DL_ERROR(E_READSTRM, S_STRINGTBL);
670 + /* if we need to fix up byte order, do it now */
671 +#ifndef _BIG_ENDIAN
672 + if (dlthis->reorder_map)
673 + dload_reorder(strbuf, ssiz, dlthis->reorder_map);
675 + if ((!sec_names_only) && (~dload_checksum(strbuf, ssiz) !=
676 + dlthis->verify.dv_str_tab_checksum)) {
677 + DL_ERROR(E_CHECKSUM, S_STRINGTBL);
679 +#else
680 + if (dlthis->dfile_hdr.df_byte_reshuffle !=
681 + HOST_BYTE_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) {
682 + /* put strings in big-endian order, not in PC order */
683 + dload_reorder(strbuf, ssiz, HOST_BYTE_ORDER(dlthis->dfile_hdr.
684 + df_byte_reshuffle));
686 + if ((!sec_names_only) && (~dload_reverse_checksum(strbuf, ssiz) !=
687 + dlthis->verify.dv_str_tab_checksum)) {
688 + DL_ERROR(E_CHECKSUM, S_STRINGTBL);
690 +#endif
691 +} /* dload_strings */
693 +/*************************************************************************
694 + * Procedure string_table_free
696 + * Parameters:
697 + * none
699 + * Effect:
700 + * Frees any state used by the string table.
702 + * WARNING:
703 + * This routine is not allowed to declare errors!
704 + *************************************************************************/
705 +static void string_table_free(struct dload_state *dlthis)
707 + if (dlthis->str_head)
708 + dlthis->mysym->Deallocate(dlthis->mysym, dlthis->str_head);
710 +} /* string_table_free */
713 + * Symbol Table Maintenance Functions
715 + * COFF symbols are read by dload_symbols(), which is called after
716 + * sections have been allocated. Symbols which might be used in
717 + * relocation (ie, not debug info) are retained in an internal temporary
718 + * compressed table (type Local_Symbol). A particular symbol is recovered
719 + * by index by calling dload_find_symbol(). dload_find_symbol
720 + * reconstructs a more explicit representation (type SLOTVEC) which is
721 + * used by reloc.c
722 + */
723 +/* real size of debug header */
724 +#define DBG_HDR_SIZE (sizeof(struct dll_module) - sizeof(struct dll_sect))
726 +static const char SYM_ERRID[] = { "symbol" };
728 +/**************************************************************************
729 + * Procedure dload_symbols
731 + * Parameters:
732 + * none
734 + * Effect:
735 + * Reads in symbols and retains ones that might be needed for relocation
736 + * purposes.
737 + ************************************************************************/
738 +/* size of symbol buffer no bigger than target data buffer, to limit stack
739 + * usage*/
740 +#define MY_SYM_BUF_SIZ (BYTE_TO_HOST(IMAGE_PACKET_SIZE)/\
741 + sizeof(struct doff_syment_t))
743 +static void dload_symbols(struct dload_state *dlthis)
745 + u32 s_count, siz, dsiz, symbols_left;
746 + u32 checks;
747 + struct Local_Symbol *sp;
748 + struct dynload_symbol *symp;
749 + struct dynload_symbol *newsym;
751 + s_count = dlthis->dfile_hdr.df_no_syms;
752 + if (s_count == 0)
753 + return;
755 + /* We keep a local symbol table for all of the symbols in the input.
756 + * This table contains only section & value info, as we do not have
757 + * to do any name processing for locals. We reuse this storage
758 + * as a temporary for .dllview record construction.
759 + * Allocate storage for the whole table.*/
760 + siz = s_count * sizeof(struct Local_Symbol);
761 + dsiz = DBG_HDR_SIZE +
762 + (sizeof(struct dll_sect) * dlthis->allocated_secn_count) +
763 + BYTE_TO_HOST_ROUND(dlthis->debug_string_size + 1);
764 + if (dsiz > siz)
765 + siz = dsiz; /* larger of symbols and .dllview temp */
766 + sp = (struct Local_Symbol *)dlthis->mysym->Allocate(dlthis->mysym, siz);
767 + if (!sp) {
768 + DL_ERROR(E_ALLOC, siz);
769 + return;
771 + dlthis->local_symtab = sp;
772 + /* Read the symbols in the input, store them in the table, and post any
773 + * globals to the global symbol table. In the process, externals
774 + become defined from the global symbol table */
775 + checks = dlthis->verify.dv_sym_tab_checksum;
776 + symbols_left = s_count;
777 + do { /* read all symbols */
778 + char *sname;
779 + u32 val;
780 + s32 delta;
781 + struct doff_syment_t *input_sym;
782 + unsigned syms_in_buf;
783 + int siz;
784 + struct doff_syment_t my_sym_buf[MY_SYM_BUF_SIZ];
785 + input_sym = my_sym_buf;
786 + syms_in_buf = symbols_left > MY_SYM_BUF_SIZ ?
787 + MY_SYM_BUF_SIZ : symbols_left;
788 + siz = syms_in_buf * sizeof(struct doff_syment_t);
789 + if (dlthis->strm->read_buffer(dlthis->strm, input_sym, siz) !=
790 + siz) {
791 + DL_ERROR(E_READSTRM, SYM_ERRID);
792 + return;
794 + if (dlthis->reorder_map)
795 + dload_reorder(input_sym, siz, dlthis->reorder_map);
797 + checks += dload_checksum(input_sym, siz);
798 + do { /* process symbols in buffer */
799 + symbols_left -= 1;
800 + /* attempt to derive the name of this symbol */
801 + sname = NULL;
802 + if (input_sym->dn_offset > 0) {
803 +#if BITS_PER_AU <= BITS_PER_BYTE
804 + if ((u32) input_sym->dn_offset <
805 + dlthis->dfile_hdr.df_strtab_size)
806 + sname = dlthis->str_head +
807 + BYTE_TO_HOST(input_sym->dn_offset);
808 + else
809 + dload_error(dlthis,
810 + "Bad name offset in symbol %d",
811 + symbols_left);
812 +#else
813 + sname = unpack_name(dlthis,
814 + input_sym->dn_offset);
815 +#endif
817 + val = input_sym->dn_value;
818 + delta = 0;
819 + sp->sclass = input_sym->dn_sclass;
820 + sp->secnn = input_sym->dn_scnum;
821 + /* if this is an undefined symbol,
822 + * define it (or fail) now */
823 + if (sp->secnn == DN_UNDEF) {
824 + /* pointless for static undefined */
825 + if (input_sym->dn_sclass != DN_EXT)
826 + goto loop_cont;
828 + /* try to define symbol from previously
829 + * loaded images */
830 + symp = dlthis->mysym->Find_Matching_Symbol
831 + (dlthis->mysym, sname);
832 + if (!symp) {
833 + DL_ERROR
834 + ("Undefined external symbol %s",
835 + sname);
836 + goto loop_cont;
838 + val = delta = symp->value;
839 + goto loop_cont;
841 + /* symbol defined by this module */
842 + if (sp->secnn > 0) { /* symbol references a section */
843 + if ((unsigned)sp->secnn <=
844 + dlthis->allocated_secn_count) {
845 + /* section was allocated */
846 + struct doff_scnhdr_t *srefp =
847 + &dlthis->sect_hdrs
848 + [sp->secnn - 1];
850 + if (input_sym->dn_sclass ==
851 + DN_STATLAB ||
852 + input_sym->dn_sclass == DN_EXTLAB){
853 + /* load */
854 + delta = srefp->ds_vaddr;
855 + } else {
856 + /* run */
857 + delta = srefp->ds_paddr;
859 + val += delta;
861 + goto loop_itr;
863 + /* This symbol is an absolute symbol */
864 + if (sp->secnn == DN_ABS && ((sp->sclass == DN_EXT) ||
865 + (sp->sclass == DN_EXTLAB))) {
866 + struct dynload_symbol *symp;
867 + symp = dlthis->mysym->Find_Matching_Symbol
868 + (dlthis->mysym, sname);
869 + if (!symp)
870 + goto loop_itr;
871 + /* This absolute symbol is already defined. */
872 + if (symp->value == input_sym->dn_value) {
873 + /* If symbol values are equal, continue
874 + * but don't add to the global symbol
875 + * table */
876 + sp->value = val;
877 + sp->delta = delta;
878 + sp += 1;
879 + input_sym += 1;
880 + continue;
881 + } else {
882 + /* If symbol values are not equal,
883 + * return with redefinition error */
884 + DL_ERROR("Absolute symbol %s is "
885 + "defined multiple times with "
886 + "different values", sname);
887 + return;
890 +loop_itr:
891 + /* if this is a global symbol, post it to the
892 + * global table */
893 + if (input_sym->dn_sclass == DN_EXT ||
894 + input_sym->dn_sclass == DN_EXTLAB) {
895 + /* Keep this global symbol for subsequent
896 + * modules. Don't complain on error, to allow
897 + * symbol API to suppress global symbols */
898 + if (!sname)
899 + goto loop_cont;
901 + newsym = dlthis->mysym->Add_To_Symbol_Table
902 + (dlthis->mysym, sname,
903 + (unsigned)dlthis->myhandle);
904 + if (newsym)
905 + newsym->value = val;
907 + } /* global */
908 +loop_cont:
909 + sp->value = val;
910 + sp->delta = delta;
911 + sp += 1;
912 + input_sym += 1;
913 + } while ((syms_in_buf -= 1) > 0); /* process sym in buffer */
914 + } while (symbols_left > 0); /* read all symbols */
915 + if (~checks)
916 + dload_error(dlthis, "Checksum of symbols failed");
918 +} /* dload_symbols */
920 +/*****************************************************************************
921 + * Procedure symbol_table_free
923 + * Parameters:
924 + * none
926 + * Effect:
927 + * Frees any state used by the symbol table.
929 + * WARNING:
930 + * This routine is not allowed to declare errors!
931 + *****************************************************************************/
932 +static void symbol_table_free(struct dload_state *dlthis)
934 + if (dlthis->local_symtab) {
935 + if (dlthis->dload_errcount) { /* blow off our symbols */
936 + dlthis->mysym->Purge_Symbol_Table(dlthis->mysym,
937 + (unsigned)dlthis->myhandle);
939 + dlthis->mysym->Deallocate(dlthis->mysym, dlthis->local_symtab);
941 +} /* symbol_table_free */
943 +/* .cinit Processing
945 + * The dynamic loader does .cinit interpretation. cload_cinit()
946 + * acts as a special write-to-target function, in that it takes relocated
947 + * data from the normal data flow, and interprets it as .cinit actions.
948 + * Because the normal data flow does not necessarily process the whole
949 + * .cinit section in one buffer, cload_cinit() must be prepared to
950 + * interpret the data piecemeal. A state machine is used for this
951 + * purpose.
952 + */
954 +/* The following are only for use by reloc.c and things it calls */
955 +static const struct LDR_SECTION_INFO CINIT_INFO_INIT = { CINITNAME, 0, 0,
956 + (LDR_ADDR) -1, 0, DLOAD_BSS, 0 };
958 +/*************************************************************************
959 + * Procedure cload_cinit
961 + * Parameters:
962 + * ipacket Pointer to data packet to be loaded
964 + * Effect:
965 + * Interprets the data in the buffer as .cinit data, and performs the
966 + * appropriate initializations.
967 + ************************************************************************/
968 +static void cload_cinit(struct dload_state *dlthis,
969 + struct image_packet_t *ipacket)
971 +#if TDATA_TO_HOST(CINIT_COUNT)*BITS_PER_AU > 16
972 + s32 init_count, left;
973 +#else
974 + s16 init_count, left;
975 +#endif
976 + unsigned char *pktp = ipacket->i_bits;
977 + unsigned char *pktend = pktp +
978 + BYTE_TO_HOST_ROUND(ipacket->i_packet_size);
979 + int temp;
980 + LDR_ADDR atmp;
981 + struct LDR_SECTION_INFO cinit_info;
983 + /* PROCESS ALL THE INITIALIZATION RECORDS IN THE BUFFER. */
984 + while (true) {
985 + left = pktend - pktp;
986 + switch (dlthis->cinit_state) {
987 + case CI_count: /* count field */
988 + if (left < TDATA_TO_HOST(CINIT_COUNT))
989 + goto loopexit;
990 + temp = dload_unpack(dlthis, (TgtAU_t *)pktp,
991 + CINIT_COUNT * TDATA_AU_BITS, 0,
992 + ROP_SGN);
993 + pktp += TDATA_TO_HOST(CINIT_COUNT);
994 + /* negative signifies BSS table, zero means done */
995 + if (temp <= 0) {
996 + dlthis->cinit_state = CI_done;
997 + break;
999 + dlthis->cinit_count = temp;
1000 + dlthis->cinit_state = CI_address;
1001 + break;
1002 +#if CINIT_ALIGN < CINIT_ADDRESS
1003 + case CI_partaddress:
1004 + pktp -= TDATA_TO_HOST(CINIT_ALIGN);
1005 + /* back up pointer into space courtesy of caller */
1006 + *(uint16_t *)pktp = dlthis->cinit_addr;
1007 + /* stuff in saved bits !! FALL THRU !! */
1008 +#endif
1009 + case CI_address: /* Address field for a copy packet */
1010 + if (left < TDATA_TO_HOST(CINIT_ADDRESS)) {
1011 +#if CINIT_ALIGN < CINIT_ADDRESS
1012 + if (left == TDATA_TO_HOST(CINIT_ALIGN)) {
1013 + /* address broken into halves */
1014 + dlthis->cinit_addr = *(uint16_t *)pktp;
1015 + /* remember 1st half */
1016 + dlthis->cinit_state = CI_partaddress;
1017 + left = 0;
1019 +#endif
1020 + goto loopexit;
1022 + atmp = dload_unpack(dlthis, (TgtAU_t *)pktp,
1023 + CINIT_ADDRESS * TDATA_AU_BITS, 0,
1024 + ROP_UNS);
1025 + pktp += TDATA_TO_HOST(CINIT_ADDRESS);
1026 +#if CINIT_PAGE_BITS > 0
1027 + dlthis->cinit_page = atmp &
1028 + ((1 << CINIT_PAGE_BITS) - 1);
1029 + atmp >>= CINIT_PAGE_BITS;
1030 +#else
1031 + dlthis->cinit_page = CINIT_DEFAULT_PAGE;
1032 +#endif
1033 + dlthis->cinit_addr = atmp;
1034 + dlthis->cinit_state = CI_copy;
1035 + break;
1036 + case CI_copy: /* copy bits to the target */
1037 + init_count = HOST_TO_TDATA(left);
1038 + if (init_count > dlthis->cinit_count)
1039 + init_count = dlthis->cinit_count;
1040 + if (init_count == 0)
1041 + goto loopexit; /* get more bits */
1042 + cinit_info = CINIT_INFO_INIT;
1043 + cinit_info.page = dlthis->cinit_page;
1044 + if (!dlthis->myio->writemem(dlthis->myio, pktp,
1045 + TDATA_TO_TADDR(dlthis->cinit_addr),
1046 + &cinit_info,
1047 + TDATA_TO_HOST(init_count))) {
1048 + dload_error(dlthis, E_INITFAIL, "write",
1049 + dlthis->cinit_addr);
1051 + dlthis->cinit_count -= init_count;
1052 + if (dlthis->cinit_count <= 0) {
1053 + dlthis->cinit_state = CI_count;
1054 + init_count = (init_count + CINIT_ALIGN - 1) &
1055 + -CINIT_ALIGN;
1056 + /* align to next init */
1058 + pktp += TDATA_TO_HOST(init_count);
1059 + dlthis->cinit_addr += init_count;
1060 + break;
1061 + case CI_done: /* no more .cinit to do */
1062 + return;
1063 + } /* switch (cinit_state) */
1064 + } /* while */
1066 +loopexit:
1067 + if (left > 0) {
1068 + dload_error(dlthis, "%d bytes left over in cinit packet", left);
1069 + dlthis->cinit_state = CI_done; /* left over bytes are bad */
1071 +} /* cload_cinit */
1073 +/* Functions to interface to reloc.c
1075 + * reloc.c is the relocation module borrowed from the linker, with
1076 + * minimal (we hope) changes for our purposes. cload_sect_data() invokes
1077 + * this module on a section to relocate and load the image data for that
1078 + * section. The actual read and write actions are supplied by the global
1079 + * routines below.
1080 + */
1082 +/************************************************************************
1083 + * Procedure relocate_packet
1085 + * Parameters:
1086 + * ipacket Pointer to an image packet to relocate
1088 + * Effect:
1089 + * Performs the required relocations on the packet. Returns a checksum
1090 + * of the relocation operations.
1091 + ************************************************************************/
1092 +#define MY_RELOC_BUF_SIZ 8
1093 +/* careful! exists at the same time as the image buffer*/
1094 +static int relocate_packet(struct dload_state *dlthis,
1095 + struct image_packet_t *ipacket, u32 *checks)
1097 + u32 rnum;
1099 + rnum = ipacket->i_num_relocs;
1100 + do { /* all relocs */
1101 + unsigned rinbuf;
1102 + int siz;
1103 + struct reloc_record_t *rp, rrec[MY_RELOC_BUF_SIZ];
1104 + rp = rrec;
1105 + rinbuf = rnum > MY_RELOC_BUF_SIZ ? MY_RELOC_BUF_SIZ : rnum;
1106 + siz = rinbuf * sizeof(struct reloc_record_t);
1107 + if (dlthis->strm->read_buffer(dlthis->strm, rp, siz) != siz) {
1108 + DL_ERROR(E_READSTRM, "relocation");
1109 + return 0;
1111 + /* reorder the bytes if need be */
1112 + if (dlthis->reorder_map)
1113 + dload_reorder(rp, siz, dlthis->reorder_map);
1115 + *checks += dload_checksum(rp, siz);
1116 + do {
1117 + /* perform the relocation operation */
1118 + dload_relocate(dlthis, (TgtAU_t *) ipacket->i_bits, rp);
1119 + rp += 1;
1120 + rnum -= 1;
1121 + } while ((rinbuf -= 1) > 0);
1122 + } while (rnum > 0); /* all relocs */
1123 + return 1;
1124 +} /* dload_read_reloc */
1126 +#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32))
1128 +/* VERY dangerous */
1129 +static const char IMAGEPAK[] = { "image packet" };
1131 +/*************************************************************************
1132 + * Procedure dload_data
1134 + * Parameters:
1135 + * none
1137 + * Effect:
1138 + * Read image data from input file, relocate it, and download it to the
1139 + * target.
1140 + ************************************************************************/
1141 +static void dload_data(struct dload_state *dlthis)
1143 + u16 curr_sect;
1144 + struct doff_scnhdr_t *sptr = dlthis->sect_hdrs;
1145 + struct LDR_SECTION_INFO *lptr = dlthis->ldr_sections;
1146 +#ifdef OPT_ZERO_COPY_LOADER
1147 + boolean bZeroCopy = false;
1148 +#endif
1149 + u8 *pDest;
1151 + struct {
1152 + struct image_packet_t ipacket;
1153 + u8 bufr[BYTE_TO_HOST(IMAGE_PACKET_SIZE)];
1154 + } ibuf;
1156 + /* Indicates whether CINIT processing has occurred */
1157 + boolean cinit_processed = false;
1159 + /* Loop through the sections and load them one at a time.
1160 + */
1161 + for (curr_sect = 0; curr_sect < dlthis->dfile_hdr.df_no_scns;
1162 + curr_sect += 1) {
1163 + if (DS_NEEDS_DOWNLOAD(sptr)) {
1164 + s32 nip;
1165 + LDR_ADDR image_offset = 0;
1166 + /* set relocation info for this section */
1167 + if (curr_sect < dlthis->allocated_secn_count)
1168 + dlthis->delta_runaddr = sptr->ds_paddr;
1169 + else {
1170 + lptr = DOFFSEC_IS_LDRSEC(sptr);
1171 + dlthis->delta_runaddr = 0;
1173 + dlthis->image_secn = lptr;
1174 +#if BITS_PER_AU > BITS_PER_BYTE
1175 + lptr->name = unpack_name(dlthis, sptr->ds_offset);
1176 +#endif
1177 + nip = sptr->ds_nipacks;
1178 + while ((nip -= 1) >= 0) { /* process packets */
1180 + s32 ipsize;
1181 + u32 checks;
1182 + /* get the fixed header bits */
1183 + if (dlthis->strm->read_buffer(dlthis->strm,
1184 + &ibuf.ipacket, IPH_SIZE) != IPH_SIZE) {
1185 + DL_ERROR(E_READSTRM, IMAGEPAK);
1186 + return;
1188 + /* reorder the header if need be */
1189 + if (dlthis->reorder_map) {
1190 + dload_reorder(&ibuf.ipacket, IPH_SIZE,
1191 + dlthis->reorder_map);
1193 + /* now read the rest of the packet */
1194 + ipsize =
1195 + BYTE_TO_HOST(DOFF_ALIGN
1196 + (ibuf.ipacket.i_packet_size));
1197 + if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) {
1198 + DL_ERROR("Bad image packet size %d",
1199 + ipsize);
1200 + return;
1202 + pDest = ibuf.bufr;
1203 +#ifdef OPT_ZERO_COPY_LOADER
1204 + bZeroCopy = false;
1205 + if (DLOAD_SECT_TYPE(sptr) != DLOAD_CINIT) {
1206 + dlthis->myio->writemem(dlthis->myio,
1207 + &pDest, lptr->load_addr +
1208 + image_offset, lptr, 0);
1209 + bZeroCopy = (pDest != ibuf.bufr);
1211 +#endif
1212 + /* End of determination */
1214 + if (dlthis->strm->read_buffer(dlthis->strm,
1215 + ibuf.bufr, ipsize) != ipsize) {
1216 + DL_ERROR(E_READSTRM, IMAGEPAK);
1217 + return;
1219 + ibuf.ipacket.i_bits = pDest;
1221 + /* reorder the bytes if need be */
1222 +#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16)
1223 + if (dlthis->reorder_map) {
1224 + dload_reorder(pDest, ipsize,
1225 + dlthis->reorder_map);
1227 + checks = dload_checksum(pDest, ipsize);
1228 +#else
1229 + if (dlthis->dfile_hdr.df_byte_reshuffle !=
1230 + TARGET_ORDER(REORDER_MAP
1231 + (BYTE_RESHUFFLE_VALUE))) {
1232 + /* put image bytes in big-endian order,
1233 + * not PC order */
1234 + dload_reorder(pDest, ipsize,
1235 + TARGET_ORDER
1236 + (dlthis->dfile_hdr.df_byte_reshuffle));
1238 +#if TARGET_AU_BITS > 8
1239 + checks = dload_reverse_checksum_16(pDest,
1240 + ipsize);
1241 +#else
1242 + checks = dload_reverse_checksum(pDest,
1243 + ipsize);
1244 +#endif
1245 +#endif
1247 + checks += dload_checksum(&ibuf.ipacket,
1248 + IPH_SIZE);
1249 + /* relocate the image bits as needed */
1250 + if (ibuf.ipacket.i_num_relocs) {
1251 + dlthis->image_offset = image_offset;
1252 + if (!relocate_packet(dlthis,
1253 + &ibuf.ipacket, &checks))
1254 + return; /* serious error */
1256 + if (~checks)
1257 + DL_ERROR(E_CHECKSUM, IMAGEPAK);
1258 + /* stuff the result into target memory */
1259 + if (DLOAD_SECT_TYPE(sptr) == DLOAD_CINIT) {
1260 + cload_cinit(dlthis, &ibuf.ipacket);
1261 + cinit_processed = true;
1262 + } else {
1263 +#ifdef OPT_ZERO_COPY_LOADER
1264 + if (!bZeroCopy) {
1265 +#endif
1267 + if (!dlthis->myio->writemem
1268 + (dlthis->myio, ibuf.bufr,
1269 + lptr->load_addr + image_offset, lptr,
1270 + BYTE_TO_HOST
1271 + (ibuf.ipacket.i_packet_size))) {
1272 + DL_ERROR(
1273 + "Write to " FMT_UI32 " failed",
1274 + lptr->load_addr + image_offset);
1276 +#ifdef OPT_ZERO_COPY_LOADER
1278 +#endif
1281 + image_offset +=
1282 + BYTE_TO_TADDR(ibuf.ipacket.i_packet_size);
1283 + } /* process packets */
1284 + /* if this is a BSS section, we may want to fill it */
1285 + if (DLOAD_SECT_TYPE(sptr) != DLOAD_BSS)
1286 + goto loop_cont;
1288 + if (!(dlthis->myoptions & DLOAD_INITBSS))
1289 + goto loop_cont;
1291 + if (cinit_processed) {
1292 + /* Don't clear BSS after load-time
1293 + * initialization */
1294 + DL_ERROR
1295 + ("Zero-initialization at " FMT_UI32 " after "
1296 + "load-time initialization!", lptr->load_addr);
1297 + goto loop_cont;
1299 + /* fill the .bss area */
1300 + dlthis->myio->fillmem(dlthis->myio,
1301 + TADDR_TO_HOST(lptr->load_addr),
1302 + lptr, TADDR_TO_HOST(lptr->size),
1303 + dload_fill_bss);
1304 + goto loop_cont;
1305 + } /* if DS_DOWNLOAD_MASK */
1306 + /* If not loading, but BSS, zero initialize */
1307 + if (DLOAD_SECT_TYPE(sptr) != DLOAD_BSS)
1308 + goto loop_cont;
1310 + if (!(dlthis->myoptions & DLOAD_INITBSS))
1311 + goto loop_cont;
1313 + if (curr_sect >= dlthis->allocated_secn_count)
1314 + lptr = DOFFSEC_IS_LDRSEC(sptr);
1316 + if (cinit_processed) {
1317 + /*Don't clear BSS after load-time initialization */
1318 + DL_ERROR(
1319 + "Zero-initialization at " FMT_UI32 " attempted after "
1320 + "load-time initialization!", lptr->load_addr);
1321 + goto loop_cont;
1323 + /* fill the .bss area */
1324 + dlthis->myio->fillmem(dlthis->myio,
1325 + TADDR_TO_HOST(lptr->load_addr), lptr,
1326 + TADDR_TO_HOST(lptr->size), dload_fill_bss);
1327 +loop_cont:
1328 + sptr += 1;
1329 + lptr += 1;
1330 + } /* load sections */
1331 +} /* dload_data */
1333 +/*************************************************************************
1334 + * Procedure dload_reorder
1336 + * Parameters:
1337 + * data 32-bit aligned pointer to data to be byte-swapped
1338 + * dsiz size of the data to be reordered in sizeof() units.
1339 + * map 32-bit map defining how to reorder the data. Value
1340 + * must be REORDER_MAP() of some permutation
1341 + * of 0x00 01 02 03
1343 + * Effect:
1344 + * Re-arranges the bytes in each word according to the map specified.
1346 + ************************************************************************/
1347 +/* mask for byte shift count */
1348 +#define SHIFT_COUNT_MASK (3 << LOG_BITS_PER_BYTE)
1350 +void dload_reorder(void *data, int dsiz, unsigned int map)
1352 + register u32 tmp, tmap, datv;
1353 + u32 *dp = (u32 *)data;
1355 + map <<= LOG_BITS_PER_BYTE; /* align map with SHIFT_COUNT_MASK */
1356 + do {
1357 + tmp = 0;
1358 + datv = *dp;
1359 + tmap = map;
1360 + do {
1361 + tmp |= (datv & BYTE_MASK) << (tmap & SHIFT_COUNT_MASK);
1362 + tmap >>= BITS_PER_BYTE;
1363 + } while (datv >>= BITS_PER_BYTE);
1364 + *dp++ = tmp;
1365 + } while ((dsiz -= sizeof(u32)) > 0);
1366 +} /* dload_reorder */
1368 +/*************************************************************************
1369 + * Procedure dload_checksum
1371 + * Parameters:
1372 + * data 32-bit aligned pointer to data to be checksummed
1373 + * siz size of the data to be checksummed in sizeof() units.
1375 + * Effect:
1376 + * Returns a checksum of the specified block
1378 + ************************************************************************/
1379 +u32 dload_checksum(void *data, unsigned siz)
1381 + u32 sum;
1382 + u32 *dp;
1383 + int left;
1385 + sum = 0;
1386 + dp = (u32 *)data;
1387 + for (left = siz; left > 0; left -= sizeof(u32))
1388 + sum += *dp++;
1389 + return sum;
1390 +} /* dload_checksum */
1392 +#if HOST_ENDIANNESS
1393 +/*************************************************************************
1394 + * Procedure dload_reverse_checksum
1396 + * Parameters:
1397 + * data 32-bit aligned pointer to data to be checksummed
1398 + * siz size of the data to be checksummed in sizeof() units.
1400 + * Effect:
1401 + * Returns a checksum of the specified block, which is assumed to be bytes
1402 + * in big-endian order.
1404 + * Notes:
1405 + * In a big-endian host, things like the string table are stored as bytes
1406 + * in host order. But dllcreate always checksums in little-endian order.
1407 + * It is most efficient to just handle the difference a word at a time.
1409 + ***********************************************************************/
1410 +u32 dload_reverse_checksum(void *data, unsigned siz)
1412 + u32 sum, temp;
1413 + u32 *dp;
1414 + int left;
1416 + sum = 0;
1417 + dp = (u32 *)data;
1419 + for (left = siz; left > 0; left -= sizeof(u32)) {
1420 + temp = *dp++;
1421 + sum += temp << BITS_PER_BYTE * 3;
1422 + sum += temp >> BITS_PER_BYTE * 3;
1423 + sum += (temp >> BITS_PER_BYTE) & (BYTE_MASK << BITS_PER_BYTE);
1424 + sum += (temp & (BYTE_MASK << BITS_PER_BYTE)) << BITS_PER_BYTE;
1427 + return sum;
1428 +} /* dload_reverse_checksum */
1430 +#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
1431 +u32 dload_reverse_checksum_16(void *data, unsigned siz)
1433 + uint_fast32_t sum, temp;
1434 + u32 *dp;
1435 + int left;
1437 + sum = 0;
1438 + dp = (u32 *)data;
1440 + for (left = siz; left > 0; left -= sizeof(u32)) {
1441 + temp = *dp++;
1442 + sum += temp << BITS_PER_BYTE * 2;
1443 + sum += temp >> BITS_PER_BYTE * 2;
1446 + return sum;
1447 +} /* dload_reverse_checksum_16 */
1448 +#endif
1449 +#endif
1451 +/*************************************************************************
1452 + * Procedure swap_words
1454 + * Parameters:
1455 + * data 32-bit aligned pointer to data to be swapped
1456 + * siz size of the data to be swapped.
1457 + * bitmap Bit map of how to swap each 32-bit word; 1 => 2 shorts,
1458 + * 0 => 1 long
1460 + * Effect:
1461 + * Swaps the specified data according to the specified map
1463 + ************************************************************************/
1464 +static void swap_words(void *data, unsigned siz, unsigned bitmap)
1466 + register int i;
1467 +#if TARGET_AU_BITS < 16
1468 + register u16 *sp;
1469 +#endif
1470 + register u32 *lp;
1472 + siz /= sizeof(u16);
1474 +#if TARGET_AU_BITS < 16
1475 + /* pass 1: do all the bytes */
1476 + i = siz;
1477 + sp = (u16 *) data;
1478 + do {
1479 + register u16 tmp;
1480 + tmp = *sp;
1481 + *sp++ = SWAP16BY8(tmp);
1482 + } while ((i -= 1) > 0);
1483 +#endif
1485 +#if TARGET_AU_BITS < 32
1486 + /* pass 2: fixup the 32-bit words */
1487 + i = siz >> 1;
1488 + lp = (u32 *) data;
1489 + do {
1490 + if ((bitmap & 1) == 0) {
1491 + register u32 tmp;
1492 + tmp = *lp;
1493 + *lp = SWAP32BY16(tmp);
1495 + lp += 1;
1496 + bitmap >>= 1;
1497 + } while ((i -= 1) > 0);
1498 +#endif
1499 +} /* swap_words */
1501 +/*************************************************************************
1502 + * Procedure copy_tgt_strings
1504 + * Parameters:
1505 + * dstp Destination address. Assumed to be 32-bit aligned
1506 + * srcp Source address. Assumed to be 32-bit aligned
1507 + * charcount Number of characters to copy.
1509 + * Effect:
1510 + * Copies strings from the source (which is in usual .dof file order on
1511 + * the loading processor) to the destination buffer (which should be in proper
1512 + * target addressable unit order). Makes sure the last string in the
1513 + * buffer is NULL terminated (for safety).
1514 + * Returns the first unused destination address.
1515 + ************************************************************************/
1516 +static char *copy_tgt_strings(void *dstp, void *srcp, unsigned charcount)
1518 + register TgtAU_t *src = (TgtAU_t *)srcp;
1519 + register TgtAU_t *dst = (TgtAU_t *)dstp;
1520 + register int cnt = charcount;
1521 + do {
1522 +#if TARGET_AU_BITS <= BITS_PER_AU
1523 + /* byte-swapping issues may exist for strings on target */
1524 + *dst++ = *src++;
1525 +#elif TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)
1526 + register TgtAU_t tmp;
1527 + tmp = *src++;
1528 + *dst++ = SWAP16BY8(tmp); /* right for TARGET_AU_BITS == 16 */
1529 +#else
1530 + *dst++ = *src++;
1531 +#endif
1532 + } while ((cnt -= (sizeof(TgtAU_t) * BITS_PER_AU / BITS_PER_BYTE)) > 0);
1533 + /*apply force to make sure that the string table has null terminator */
1534 +#if (BITS_PER_AU == BITS_PER_BYTE) && (TARGET_AU_BITS == BITS_PER_BYTE)
1535 + dst[-1] = 0;
1536 +#elif TARGET_BIG_ENDIAN
1537 + dst[-1] &= ~BYTE_MASK; /* big-endian */
1538 +#else
1539 + dst[-1] &= (1 << (BITS_PER_AU - BITS_PER_BYTE)) - 1; /* little endian */
1540 +#endif
1541 + return (char *)dst;
1542 +} /* copy_tgt_strings */
1544 +/*************************************************************************
1545 + * Procedure init_module_handle
1547 + * Parameters:
1548 + * none
1550 + * Effect:
1551 + * Initializes the module handle we use to enable unloading, and installs
1552 + * the debug information required by the target.
1554 + * Notes:
1555 + * The handle returned from Dynamic_Load_Module needs to encapsulate all the
1556 + * allocations done for the module, and enable them plus the modules symbols to
1557 + * be deallocated.
1559 + ************************************************************************/
1560 +#ifndef _BIG_ENDIAN
1561 +static const struct LDR_SECTION_INFO DLLVIEW_INFO_INIT = { ".dllview", 0, 0,
1562 + (LDR_ADDR) -1, DBG_LIST_PAGE, DLOAD_DATA, 0 };
1563 +#else
1564 +static const struct LDR_SECTION_INFO DLLVIEW_INFO_INIT = { ".dllview", 0, 0,
1565 + (LDR_ADDR) -1, DLOAD_DATA, DBG_LIST_PAGE, 0 };
1566 +#endif
1567 +static void init_module_handle(struct dload_state *dlthis)
1569 + struct my_handle *hndl;
1570 + u16 curr_sect;
1571 + struct LDR_SECTION_INFO *asecs;
1572 + struct dll_module *dbmod;
1573 + struct dll_sect *dbsec;
1574 + struct dbg_mirror_root *mlist;
1575 + register char *cp;
1576 + struct modules_header mhdr;
1577 + struct LDR_SECTION_INFO dllview_info;
1578 + struct dynload_symbol *debug_mirror_sym;
1579 + hndl = dlthis->myhandle;
1580 + if (!hndl)
1581 + return; /* must be errors detected, so forget it */
1582 + hndl->secn_count = dlthis->allocated_secn_count << 1;
1583 +#ifndef TARGET_ENDIANNESS
1584 + if (dlthis->big_e_target)
1585 + hndl->secn_count += 1; /* flag for big-endian */
1586 +#endif
1587 + if (dlthis->dload_errcount)
1588 + return; /* abandon if errors detected */
1589 + /* Locate the symbol that names the header for the CCS debug list
1590 + of modules. If not found, we just don't generate the debug record.
1591 + If found, we create our modules list. We make sure to create the
1592 + LOADER_DLLVIEW_ROOT even if there is no relocation info to record,
1593 + just to try to put both symbols in the same symbol table and
1594 + module.*/
1595 + debug_mirror_sym = dlthis->mysym->Find_Matching_Symbol(dlthis->mysym,
1596 + LOADER_DLLVIEW_ROOT);
1597 + if (!debug_mirror_sym) {
1598 + struct dynload_symbol *dlmodsym;
1599 + struct dbg_mirror_root *mlst;
1601 + /* our root symbol is not yet present;
1602 + check if we have DLModules defined */
1603 + dlmodsym = dlthis->mysym->Find_Matching_Symbol(dlthis->mysym,
1604 + LINKER_MODULES_HEADER);
1605 + if (!dlmodsym)
1606 + return; /* no DLModules list so no debug info */
1607 + /* if we have DLModules defined, construct our header */
1608 + mlst = (struct dbg_mirror_root *)
1609 + dlthis->mysym->Allocate(dlthis->mysym,
1610 + sizeof(struct dbg_mirror_root));
1611 + if (!mlst) {
1612 + DL_ERROR(E_ALLOC, sizeof(struct dbg_mirror_root));
1613 + return;
1615 + mlst->hnext = NULL;
1616 + mlst->changes = 0;
1617 + mlst->refcount = 0;
1618 + mlst->dbthis = TDATA_TO_TADDR(dlmodsym->value);
1619 + /* add our root symbol */
1620 + debug_mirror_sym = dlthis->mysym->Add_To_Symbol_Table
1621 + (dlthis->mysym, LOADER_DLLVIEW_ROOT,
1622 + (unsigned)dlthis->myhandle);
1623 + if (!debug_mirror_sym) {
1624 + /* failed, recover memory */
1625 + dlthis->mysym->Deallocate(dlthis->mysym, mlst);
1626 + return;
1628 + debug_mirror_sym->value = (u32)mlst;
1630 + /* First create the DLLview record and stuff it into the buffer.
1631 + Then write it to the DSP. Record pertinent locations in our hndl,
1632 + and add it to the per-processor list of handles with debug info.*/
1633 +#ifndef DEBUG_HEADER_IN_LOADER
1634 + mlist = (struct dbg_mirror_root *)debug_mirror_sym->value;
1635 + if (!mlist)
1636 + return;
1637 +#else
1638 + mlist = (struct dbg_mirror_root *)&debug_list_header;
1639 +#endif
1640 + hndl->dm.hroot = mlist; /* set pointer to root into our handle */
1641 + if (!dlthis->allocated_secn_count)
1642 + return; /* no load addresses to be recorded */
1643 + /* reuse temporary symbol storage */
1644 + dbmod = (struct dll_module *) dlthis->local_symtab;
1645 + /* Create the DLLview record in the memory we retain for our handle*/
1646 + dbmod->num_sects = dlthis->allocated_secn_count;
1647 + dbmod->timestamp = dlthis->verify.dv_timdat;
1648 + dbmod->version = INIT_VERSION;
1649 + dbmod->verification = VERIFICATION;
1650 + asecs = dlthis->ldr_sections;
1651 + dbsec = dbmod->sects;
1652 + for (curr_sect = dlthis->allocated_secn_count;
1653 + curr_sect > 0; curr_sect -= 1) {
1654 + dbsec->sect_load_adr = asecs->load_addr;
1655 + dbsec->sect_run_adr = asecs->run_addr;
1656 + dbsec += 1;
1657 + asecs += 1;
1659 + /* now cram in the names */
1660 + cp = copy_tgt_strings(dbsec, dlthis->str_head,
1661 + dlthis->debug_string_size);
1663 + /* round off the size of the debug record, and remember same */
1664 + hndl->dm.dbsiz = HOST_TO_TDATA_ROUND(cp - (char *)dbmod);
1665 + *cp = 0; /* strictly to make our test harness happy */
1666 + dllview_info = DLLVIEW_INFO_INIT;
1667 + dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz);
1668 + /* Initialize memory context to default heap */
1669 + dllview_info.context = 0;
1670 + hndl->dm.context = 0;
1671 + /* fill in next pointer and size */
1672 + if (mlist->hnext) {
1673 + dbmod->next_module = TADDR_TO_TDATA(mlist->hnext->dm.dbthis);
1674 + dbmod->next_module_size = mlist->hnext->dm.dbsiz;
1675 + } else {
1676 + dbmod->next_module_size = 0;
1677 + dbmod->next_module = 0;
1679 + /* allocate memory for on-DSP DLLview debug record */
1680 + if (!dlthis->myalloc)
1681 + return;
1682 + if (!dlthis->myalloc->Allocate(dlthis->myalloc, &dllview_info,
1683 + HOST_TO_TADDR(sizeof(u32)))) {
1684 + return;
1686 + /* Store load address of .dllview section */
1687 + hndl->dm.dbthis = dllview_info.load_addr;
1688 + /* Store memory context (segid) in which .dllview section
1689 + * was allocated */
1690 + hndl->dm.context = dllview_info.context;
1691 + mlist->refcount += 1;
1692 + /* swap bytes in the entire debug record, but not the string table */
1693 + if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) {
1694 + swap_words(dbmod, (char *)dbsec - (char *)dbmod,
1695 + DLL_MODULE_BITMAP);
1697 + /* Update the DLLview list on the DSP write new record */
1698 + if (!dlthis->myio->writemem(dlthis->myio, dbmod,
1699 + dllview_info.load_addr, &dllview_info,
1700 + TADDR_TO_HOST(dllview_info.size))) {
1701 + return;
1703 + /* write new header */
1704 + mhdr.first_module_size = hndl->dm.dbsiz;
1705 + mhdr.first_module = TADDR_TO_TDATA(dllview_info.load_addr);
1706 + /* swap bytes in the module header, if needed */
1707 + if (TARGET_ENDIANNESS_DIFFERS(TARGET_BIG_ENDIAN)) {
1708 + swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16),
1709 + MODULES_HEADER_BITMAP);
1711 + dllview_info = DLLVIEW_INFO_INIT;
1712 + if (!dlthis->myio->writemem(dlthis->myio, &mhdr, mlist->dbthis,
1713 + &dllview_info, sizeof(struct modules_header) -
1714 + sizeof(u16))) {
1715 + return;
1717 + /* Add the module handle to this processor's list
1718 + of handles with debug info */
1719 + hndl->dm.hnext = mlist->hnext;
1720 + if (hndl->dm.hnext)
1721 + hndl->dm.hnext->dm.hprev = hndl;
1722 + hndl->dm.hprev = (struct my_handle *) mlist;
1723 + mlist->hnext = hndl; /* insert after root*/
1724 +} /* init_module_handle */
1726 +/*************************************************************************
1727 + * Procedure Dynamic_Unload_Module
1729 + * Parameters:
1730 + * mhandle A module handle from Dynamic_Load_Module
1731 + * syms Host-side symbol table and malloc/free functions
1732 + * alloc Target-side memory allocation
1734 + * Effect:
1735 + * The module specified by mhandle is unloaded. Unloading causes all
1736 + * target memory to be deallocated, all symbols defined by the module to
1737 + * be purged, and any host-side storage used by the dynamic loader for
1738 + * this module to be released.
1740 + * Returns:
1741 + * Zero for success. On error, the number of errors detected is returned.
1742 + * Individual errors are reported using syms->Error_Report().
1743 + ************************************************************************/
1744 +extern int Dynamic_Unload_Module(DLOAD_mhandle mhandle,
1745 + struct Dynamic_Loader_Sym *syms,
1746 + struct Dynamic_Loader_Allocate *alloc,
1747 + struct Dynamic_Loader_Initialize *init)
1749 + s16 curr_sect;
1750 + struct LDR_SECTION_INFO *asecs;
1751 + struct my_handle *hndl;
1752 + struct dbg_mirror_root *root;
1753 + unsigned errcount = 0;
1754 + struct LDR_SECTION_INFO dllview_info = DLLVIEW_INFO_INIT;
1755 + struct modules_header mhdr;
1757 + hndl = (struct my_handle *)mhandle;
1758 + if (!hndl)
1759 + return 0; /* if handle is null, nothing to do */
1760 + /* Clear out the module symbols
1761 + * Note that if this is the module that defined MODULES_HEADER
1762 + (the head of the target debug list)
1763 + * then this operation will blow away that symbol.
1764 + It will therefore be impossible for subsequent
1765 + * operations to add entries to this un-referenceable list.*/
1766 + if (!syms)
1767 + return 1;
1768 + syms->Purge_Symbol_Table(syms, (unsigned) hndl);
1769 + /* Deallocate target memory for sections */
1770 + asecs = hndl->secns;
1771 + if (alloc)
1772 + for (curr_sect = (hndl->secn_count >> 1); curr_sect > 0;
1773 + curr_sect -= 1) {
1774 + asecs->name = NULL;
1775 + alloc->Deallocate(alloc, asecs++);
1777 + root = hndl->dm.hroot;
1778 + if (!root) {
1779 + /* there is a debug list containing this module */
1780 + goto func_end;
1782 + if (!hndl->dm.dbthis) { /* target-side dllview record exists */
1783 + goto loop_end;
1785 + /* Retrieve memory context in which .dllview was allocated */
1786 + dllview_info.context = hndl->dm.context;
1787 + if (hndl->dm.hprev == hndl)
1788 + goto exitunltgt;
1790 + /* target-side dllview record is in list */
1791 + /* dequeue this record from our GPP-side mirror list */
1792 + hndl->dm.hprev->dm.hnext = hndl->dm.hnext;
1793 + if (hndl->dm.hnext)
1794 + hndl->dm.hnext->dm.hprev = hndl->dm.hprev;
1795 + /* Update next_module of previous entry in target list
1796 + * We are using mhdr here as a surrogate for either a
1797 + struct modules_header or a dll_module */
1798 + if (hndl->dm.hnext) {
1799 + mhdr.first_module = TADDR_TO_TDATA(hndl->dm.hnext->dm.dbthis);
1800 + mhdr.first_module_size = hndl->dm.hnext->dm.dbsiz;
1801 + } else {
1802 + mhdr.first_module = 0;
1803 + mhdr.first_module_size = 0;
1805 + if (!init)
1806 + goto exitunltgt;
1808 + if (!init->connect(init)) {
1809 + dload_syms_error(syms, E_ICONNECT);
1810 + errcount += 1;
1811 + goto exitunltgt;
1813 + /* swap bytes in the module header, if needed */
1814 + if (TARGET_ENDIANNESS_DIFFERS(hndl->secn_count & 0x1)) {
1815 + swap_words(&mhdr, sizeof(struct modules_header) - sizeof(u16),
1816 + MODULES_HEADER_BITMAP);
1818 + if (!init->writemem(init, &mhdr, hndl->dm.hprev->dm.dbthis,
1819 + &dllview_info, sizeof(struct modules_header) -
1820 + sizeof(mhdr.update_flag))) {
1821 + dload_syms_error(syms, E_DLVWRITE);
1822 + errcount += 1;
1824 + /* update change counter */
1825 + root->changes += 1;
1826 + if (!init->writemem(init, &(root->changes),
1827 + root->dbthis + HOST_TO_TADDR
1828 + (sizeof(mhdr.first_module) +
1829 + sizeof(mhdr.first_module_size)),
1830 + &dllview_info,
1831 + sizeof(mhdr.update_flag))) {
1832 + dload_syms_error(syms, E_DLVWRITE);
1833 + errcount += 1;
1835 + init->release(init);
1836 +exitunltgt:
1837 + /* release target storage */
1838 + dllview_info.size = TDATA_TO_TADDR(hndl->dm.dbsiz);
1839 + dllview_info.load_addr = hndl->dm.dbthis;
1840 + if (alloc)
1841 + alloc->Deallocate(alloc, &dllview_info);
1842 + root->refcount -= 1;
1843 + /* target-side dllview record exists */
1844 +loop_end:
1845 +#ifndef DEBUG_HEADER_IN_LOADER
1846 + if (root->refcount <= 0) {
1847 + /* if all references gone, blow off the header */
1848 + /* our root symbol may be gone due to the Purge above,
1849 + but if not, do not destroy the root */
1850 + if (syms->Find_Matching_Symbol
1851 + (syms, LOADER_DLLVIEW_ROOT) == NULL)
1852 + syms->Deallocate(syms, root);
1854 +#endif
1855 +func_end:
1856 + /* there is a debug list containing this module */
1857 + syms->Deallocate(syms, mhandle); /* release our storage */
1858 + return errcount;
1859 +} /* Dynamic_Unload_Module */
1861 +#if BITS_PER_AU > BITS_PER_BYTE
1862 +/*************************************************************************
1863 + * Procedure unpack_name
1865 + * Parameters:
1866 + * soffset Byte offset into the string table
1868 + * Effect:
1869 + * Returns a pointer to the string specified by the offset supplied, or
1870 + * NULL for error.
1872 + ************************************************************************/
1873 +static char *unpack_name(struct dload_state *dlthis, u32 soffset)
1875 + u8 tmp, *src;
1876 + char *dst;
1878 + if (soffset >= dlthis->dfile_hdr.df_strtab_size) {
1879 + dload_error(dlthis, "Bad string table offset " FMT_UI32,
1880 + soffset);
1881 + return NULL;
1883 + src = (uint_least8_t *)dlthis->str_head +
1884 + (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE));
1885 + dst = dlthis->str_temp;
1886 + if (soffset & 1)
1887 + *dst++ = *src++; /* only 1 character in first word */
1888 + do {
1889 + tmp = *src++;
1890 + *dst = (tmp >> BITS_PER_BYTE);
1891 + if (!(*dst++))
1892 + break;
1893 + } while ((*dst++ = tmp & BYTE_MASK));
1894 + dlthis->temp_len = dst - dlthis->str_temp;
1895 + /* squirrel away length including terminating null */
1896 + return dlthis->str_temp;
1897 +} /* unpack_name */
1898 +#endif
1899 Index: lk/drivers/dsp/bridge/dynload/dlclasses_hdr.h
1900 ===================================================================
1901 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1902 +++ lk/drivers/dsp/bridge/dynload/dlclasses_hdr.h 2008-08-18 10:38:35.000000000 +0300
1903 @@ -0,0 +1,41 @@
1905 + * linux/drivers/dsp/bridge/dynload/dlclasses_hdr.h
1907 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
1909 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
1911 + * This package is free software; you can redistribute it and/or modify
1912 + * it under the terms of the GNU General Public License version 2 as
1913 + * published by the Free Software Foundation.
1915 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1916 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1917 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1918 + */
1922 +#ifndef _DLCLASSES_HDR_H
1923 +#define _DLCLASSES_HDR_H
1925 +/*****************************************************************************
1926 + *****************************************************************************
1928 + * DLCLASSES_HDR.H
1930 + * Sample classes in support of the dynamic loader
1932 + * These are just concrete derivations of the virtual ones in dynamic_loader.h
1933 + * with a few additional interfaces for init, etc.
1934 + *****************************************************************************
1935 + *****************************************************************************/
1937 +#include "dynamic_loader.h"
1939 +#include "DLstream.h"
1940 +#include "DLsymtab.h"
1941 +#include "DLalloc.h"
1942 +#include "DLinit.h"
1944 +#endif /* _DLCLASSES_HDR_H */
1945 Index: lk/drivers/dsp/bridge/dynload/dload_internal.h
1946 ===================================================================
1947 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
1948 +++ lk/drivers/dsp/bridge/dynload/dload_internal.h 2008-08-18 10:38:35.000000000 +0300
1949 @@ -0,0 +1,237 @@
1951 + * linux/drivers/dsp/bridge/dynload/dload_internal.h
1953 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
1955 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
1957 + * This package is free software; you can redistribute it and/or modify
1958 + * it under the terms of the GNU General Public License version 2 as
1959 + * published by the Free Software Foundation.
1961 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
1962 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
1963 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1964 + */
1968 +#ifndef __DLOAD_INTERNAL__
1969 +#define __DLOAD_INTERNAL__
1971 +#include <linux/types.h>
1974 + * Internal state definitions for the dynamic loader
1975 + */
1977 +#define TRUE 1
1978 +#define FALSE 0
1979 +typedef int boolean;
1982 +/* type used for relocation intermediate results */
1983 +typedef s32 RVALUE;
1985 +/* unsigned version of same; must have at least as many bits */
1986 +typedef u32 URVALUE;
1989 + * Dynamic loader configuration constants
1990 + */
1991 +/* error issued if input has more sections than this limit */
1992 +#define REASONABLE_SECTION_LIMIT 100
1994 +/* (Addressable unit) value used to clear BSS section */
1995 +#define dload_fill_bss 0
1998 + * Reorder maps explained (?)
2000 + * The doff file format defines a 32-bit pattern used to determine the
2001 + * byte order of an image being read. That value is
2002 + * BYTE_RESHUFFLE_VALUE == 0x00010203
2003 + * For purposes of the reorder routine, we would rather have the all-is-OK
2004 + * for 32-bits pattern be 0x03020100. This first macro makes the
2005 + * translation from doff file header value to MAP value: */
2006 +#define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303)
2007 +/* This translation is made in dload_headers. Thereafter, the all-is-OK
2008 + * value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE).
2009 + * But sadly, not all bits of the doff file are 32-bit integers.
2010 + * The notable exceptions are strings and image bits.
2011 + * Strings obey host byte order: */
2012 +#if defined(_BIG_ENDIAN)
2013 +#define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
2014 +#else
2015 +#define HOST_BYTE_ORDER(cookedmap) (cookedmap)
2016 +#endif
2017 +/* Target bits consist of target AUs (could be bytes, or 16-bits,
2018 + * or 32-bits) stored as an array in host order. A target order
2019 + * map is defined by: */
2020 +#if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16
2021 +#define TARGET_ORDER(cookedmap) (cookedmap)
2022 +#elif TARGET_AU_BITS > 8
2023 +#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202)
2024 +#else
2025 +#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
2026 +#endif
2028 +/* forward declaration for handle returned by dynamic loader */
2029 +struct my_handle;
2032 + * a list of module handles, which mirrors the debug list on the target
2033 + */
2034 +struct dbg_mirror_root {
2035 + /* must be same as dbg_mirror_list; __DLModules address on target */
2036 + u32 dbthis;
2037 + struct my_handle *hnext; /* must be same as dbg_mirror_list */
2038 + u16 changes; /* change counter */
2039 + u16 refcount; /* number of modules referencing this root */
2040 +} ;
2042 +struct dbg_mirror_list {
2043 + u32 dbthis;
2044 + struct my_handle *hnext, *hprev;
2045 + struct dbg_mirror_root *hroot;
2046 + u16 dbsiz;
2047 + u32 context; /* Save context for .dllview memory allocation */
2048 +} ;
2050 +#define VARIABLE_SIZE 1
2052 + * the structure we actually return as an opaque module handle
2053 + */
2054 +struct my_handle {
2055 + struct dbg_mirror_list dm; /* !!! must be first !!! */
2056 + /* sections following << 1, LSB is set for big-endian target */
2057 + u16 secn_count;
2058 + struct LDR_SECTION_INFO secns[VARIABLE_SIZE];
2059 +} ;
2060 +#define MY_HANDLE_SIZE (sizeof(struct my_handle) -\
2061 + sizeof(struct LDR_SECTION_INFO))
2062 +/* real size of my_handle */
2065 + * reduced symbol structure used for symbols during relocation
2066 + */
2067 +struct Local_Symbol {
2068 + s32 value; /* Relocated symbol value */
2069 + s32 delta; /* Original value in input file */
2070 + s16 secnn; /* section number */
2071 + s16 sclass; /* symbol class */
2072 +} ;
2075 + * States of the .cinit state machine
2076 + */
2077 +enum cinit_mode {
2078 + CI_count = 0, /* expecting a count */
2079 + CI_address, /* expecting an address */
2080 +#if CINIT_ALIGN < CINIT_ADDRESS /* handle case of partial address field */
2081 + CI_partaddress, /* have only part of the address */
2082 +#endif
2083 + CI_copy, /* in the middle of copying data */
2084 + CI_done /* end of .cinit table */
2088 + * The internal state of the dynamic loader, which is passed around as
2089 + * an object
2090 + */
2091 +struct dload_state {
2092 + struct Dynamic_Loader_Stream *strm; /* The module input stream */
2093 + struct Dynamic_Loader_Sym *mysym; /* Symbols for this session */
2094 + struct Dynamic_Loader_Allocate *myalloc; /* target memory allocator */
2095 + struct Dynamic_Loader_Initialize *myio; /* target memory initializer */
2096 + unsigned myoptions; /* Options parameter Dynamic_Load_Module */
2098 + char *str_head; /* Pointer to string table */
2099 +#if BITS_PER_AU > BITS_PER_BYTE
2100 + char *str_temp; /* Pointer to temporary buffer for strings */
2101 + /* big enough to hold longest string */
2102 + unsigned temp_len; /* length of last temporary string */
2103 + char *xstrings; /* Pointer to buffer for expanded */
2104 + /* strings for sec names */
2105 +#endif
2106 + /* Total size of strings for DLLView section names */
2107 + unsigned debug_string_size;
2108 + /* Pointer to parallel section info for allocated sections only */
2109 + struct doff_scnhdr_t *sect_hdrs; /* Pointer to section table */
2110 + struct LDR_SECTION_INFO *ldr_sections;
2111 +#if TMS32060
2112 + /* The address of the start of the .bss section */
2113 + LDR_ADDR bss_run_base;
2114 +#endif
2115 + struct Local_Symbol *local_symtab; /* Relocation symbol table */
2117 + /* pointer to DL section info for the section being relocated */
2118 + struct LDR_SECTION_INFO *image_secn;
2119 + /* change in run address for current section during relocation */
2120 + LDR_ADDR delta_runaddr;
2121 + LDR_ADDR image_offset; /* offset of current packet in section */
2122 + enum cinit_mode cinit_state; /* current state of cload_cinit() */
2123 + int cinit_count; /* the current count */
2124 + LDR_ADDR cinit_addr; /* the current address */
2125 + s16 cinit_page; /* the current page */
2126 + /* Handle to be returned by Dynamic_Load_Module */
2127 + struct my_handle *myhandle;
2128 + unsigned dload_errcount; /* Total # of errors reported so far */
2129 + /* Number of target sections that require allocation and relocation */
2130 + unsigned allocated_secn_count;
2131 +#ifndef TARGET_ENDIANNESS
2132 + boolean big_e_target; /* Target data in big-endian format */
2133 +#endif
2134 + /* map for reordering bytes, 0 if not needed */
2135 + u32 reorder_map;
2136 + struct doff_filehdr_t dfile_hdr; /* DOFF file header structure */
2137 + struct doff_verify_rec_t verify; /* Verify record */
2139 + int relstkidx; /* index into relocation value stack */
2140 + /* relocation value stack used in relexp.c */
2141 + RVALUE relstk[STATIC_EXPR_STK_SIZE];
2143 +} ;
2145 +#ifdef TARGET_ENDIANNESS
2146 +#define TARGET_BIG_ENDIAN TARGET_ENDIANNESS
2147 +#else
2148 +#define TARGET_BIG_ENDIAN (dlthis->big_e_target)
2149 +#endif
2152 + * Exports from cload.c to rest of the world
2153 + */
2154 +extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...);
2155 +extern void dload_syms_error(struct Dynamic_Loader_Sym *syms,
2156 + const char *errtxt, ...);
2157 +extern void dload_headers(struct dload_state *dlthis);
2158 +extern void dload_strings(struct dload_state *dlthis, boolean sec_names_only);
2159 +extern void dload_sections(struct dload_state *dlthis);
2160 +extern void dload_reorder(void *data, int dsiz, u32 map);
2161 +extern u32 dload_checksum(void *data, unsigned siz);
2163 +#if HOST_ENDIANNESS
2164 +extern uint32_t dload_reverse_checksum(void *data, unsigned siz);
2165 +#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
2166 +extern uint32_t dload_reverse_checksum_16(void *data, unsigned siz);
2167 +#endif
2168 +#endif
2170 +#define is_data_scn(zzz) (DLOAD_SECTION_TYPE((zzz)->type) != DLOAD_TEXT)
2171 +#define is_data_scn_num(zzz) \
2172 + (DLOAD_SECT_TYPE(&dlthis->sect_hdrs[(zzz)-1]) != DLOAD_TEXT)
2175 + * exported by reloc.c
2176 + */
2177 +extern void dload_relocate(struct dload_state *dlthis, TgtAU_t *data,
2178 + struct reloc_record_t *rp);
2180 +extern RVALUE dload_unpack(struct dload_state *dlthis, TgtAU_t *data,
2181 + int fieldsz, int offset, unsigned sgn);
2183 +extern int dload_repack(struct dload_state *dlthis, RVALUE val, TgtAU_t *data,
2184 + int fieldsz, int offset, unsigned sgn);
2186 +#endif /* __DLOAD_INTERNAL__ */
2187 Index: lk/drivers/dsp/bridge/dynload/doff.h
2188 ===================================================================
2189 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2190 +++ lk/drivers/dsp/bridge/dynload/doff.h 2008-08-18 10:38:35.000000000 +0300
2191 @@ -0,0 +1,347 @@
2193 + * linux/drivers/dsp/bridge/dynload/doff.h
2195 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
2197 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
2199 + * This package is free software; you can redistribute it and/or modify
2200 + * it under the terms of the GNU General Public License version 2 as
2201 + * published by the Free Software Foundation.
2203 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2204 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2205 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2206 + */
2209 +/*****************************************************************************/
2210 +/* DOFF.H - Structures & definitions used for dynamically */
2211 +/* loaded modules file format. This format is a reformatted */
2212 +/* version of COFF.(see coff.h for details) It optimizes the */
2213 +/* layout for the dynamic loader. */
2214 +/* */
2215 +/* .dof files, when viewed as a sequence of 32-bit integers, look the same */
2216 +/* on big-endian and little-endian machines. */
2217 +/*****************************************************************************/
2218 +#ifndef _DOFF_H
2219 +#define _DOFF_H
2221 +#ifndef UINT32_C
2222 +#define UINT32_C(zzz) ((u32)zzz)
2223 +#endif
2225 +#define BYTE_RESHUFFLE_VALUE UINT32_C(0x00010203)
2227 +/* DOFF file header containing fields categorizing the remainder of the file */
2228 +struct doff_filehdr_t {
2230 + /* string table size, including filename, in bytes */
2231 + u32 df_strtab_size;
2233 + /* entry point if one exists */
2234 + u32 df_entrypt;
2236 + /* identifies byte ordering of file;
2237 + * always set to BYTE_RESHUFFLE_VALUE */
2238 + u32 df_byte_reshuffle;
2240 + /* Size of the string table up to and including the last section name */
2241 + /* Size includes the name of the COFF file also */
2242 + u32 df_scn_name_size;
2244 +#ifndef _BIG_ENDIAN
2245 + /* number of symbols */
2246 + u16 df_no_syms;
2248 + /* length in bytes of the longest string, including terminating NULL */
2249 + /* excludes the name of the file */
2250 + u16 df_max_str_len;
2252 + /* total number of sections including no-load ones */
2253 + u16 df_no_scns;
2255 + /* number of sections containing target code allocated or downloaded */
2256 + u16 df_target_scns;
2258 + /* unique id for dll file format & version */
2259 + u16 df_doff_version;
2261 + /* identifies ISA */
2262 + u16 df_target_id;
2264 + /* useful file flags */
2265 + u16 df_flags;
2267 + /* section reference for entry point, N_UNDEF for none, */
2268 + /* N_ABS for absolute address */
2269 + s16 df_entry_secn;
2270 +#else
2271 + /* length of the longest string, including terminating NULL */
2272 + u16 df_max_str_len;
2274 + /* number of symbols */
2275 + u16 df_no_syms;
2277 + /* number of sections containing target code allocated or downloaded */
2278 + u16 df_target_scns;
2280 + /* total number of sections including no-load ones */
2281 + u16 df_no_scns;
2283 + /* identifies ISA */
2284 + u16 df_target_id;
2286 + /* unique id for dll file format & version */
2287 + u16 df_doff_version;
2289 + /* section reference for entry point, N_UNDEF for none, */
2290 + /* N_ABS for absolute address */
2291 + s16 df_entry_secn;
2293 + /* useful file flags */
2294 + u16 df_flags;
2295 +#endif
2296 + /* checksum for file header record */
2297 + u32 df_checksum;
2299 +} ;
2301 +/* flags in the df_flags field */
2302 +#define DF_LITTLE 0x100
2303 +#define DF_BIG 0x200
2304 +#define DF_BYTE_ORDER (DF_LITTLE | DF_BIG)
2306 +/* Supported processors */
2307 +#define TMS470_ID 0x97
2308 +#define LEAD_ID 0x98
2309 +#define TMS32060_ID 0x99
2310 +#define LEAD3_ID 0x9c
2312 +/* Primary processor for loading */
2313 +#if TMS32060
2314 +#define TARGET_ID TMS32060_ID
2315 +#endif
2317 +/* Verification record containing values used to test integrity of the bits */
2318 +struct doff_verify_rec_t {
2320 + /* time and date stamp */
2321 + u32 dv_timdat;
2323 + /* checksum for all section records */
2324 + u32 dv_scn_rec_checksum;
2326 + /* checksum for string table */
2327 + u32 dv_str_tab_checksum;
2329 + /* checksum for symbol table */
2330 + u32 dv_sym_tab_checksum;
2332 + /* checksum for verification record */
2333 + u32 dv_verify_rec_checksum;
2335 +} ;
2337 +/* String table is an array of null-terminated strings. The first entry is
2338 + * the filename, which is added by DLLcreate. No new structure definitions
2339 + * are required.
2340 + */
2342 +/* Section Records including information on the corresponding image packets */
2344 + * !!WARNING!!
2346 + * This structure is expected to match in form LDR_SECTION_INFO in
2347 + * dynamic_loader.h
2348 + */
2350 +struct doff_scnhdr_t {
2352 + s32 ds_offset; /* offset into string table of name */
2353 + s32 ds_paddr; /* RUN address, in target AU */
2354 + s32 ds_vaddr; /* LOAD address, in target AU */
2355 + s32 ds_size; /* section size, in target AU */
2356 +#ifndef _BIG_ENDIAN
2357 + u16 ds_page; /* memory page id */
2358 + u16 ds_flags; /* section flags */
2359 +#else
2360 + u16 ds_flags; /* section flags */
2361 + u16 ds_page; /* memory page id */
2362 +#endif
2363 + u32 ds_first_pkt_offset;
2364 + /* Absolute byte offset into the file */
2365 + /* where the first image record resides */
2367 + s32 ds_nipacks; /* number of image packets */
2371 +/* Symbol table entry */
2372 +struct doff_syment_t {
2374 + s32 dn_offset; /* offset into string table of name */
2375 + s32 dn_value; /* value of symbol */
2376 +#ifndef _BIG_ENDIAN
2377 + s16 dn_scnum; /* section number */
2378 + s16 dn_sclass; /* storage class */
2379 +#else
2380 + s16 dn_sclass; /* storage class */
2381 + s16 dn_scnum; /* section number, 1-based */
2382 +#endif
2384 +} ;
2386 +/* special values for dn_scnum */
2387 +#define DN_UNDEF 0 /* undefined symbol */
2388 +#define DN_ABS (-1) /* value of symbol is absolute */
2389 +/* special values for dn_sclass */
2390 +#define DN_EXT 2
2391 +#define DN_STATLAB 20
2392 +#define DN_EXTLAB 21
2394 +/* Default value of image bits in packet */
2395 +/* Configurable by user on the command line */
2396 +#define IMAGE_PACKET_SIZE 1024
2398 +/* An image packet contains a chunk of data from a section along with */
2399 +/* information necessary for its processing. */
2400 +struct image_packet_t {
2402 + s32 i_num_relocs; /* number of relocations for */
2403 + /* this packet */
2405 + s32 i_packet_size; /* number of bytes in array */
2406 + /* "bits" occupied by */
2407 + /* valid data. Could be */
2408 + /* < IMAGE_PACKET_SIZE to */
2409 + /* prevent splitting a */
2410 + /* relocation across packets. */
2411 + /* Last packet of a section */
2412 + /* will most likely contain */
2413 + /* < IMAGE_PACKET_SIZE bytes */
2414 + /* of valid data */
2416 + s32 i_checksum; /* Checksum for image packet */
2417 + /* and the corresponding */
2418 + /* relocation records */
2420 + u8 *i_bits; /* Actual data in section */
2424 +/* The relocation structure definition matches the COFF version. Offsets */
2425 +/* however are relative to the image packet base not the section base. */
2426 +struct reloc_record_t {
2428 + s32 r_vaddr;
2430 + /* expressed in target AUs */
2432 + union {
2433 + struct {
2434 +#ifndef _BIG_ENDIAN
2435 + u8 _offset; /* bit offset of rel fld */
2436 + u8 _fieldsz; /* size of rel fld */
2437 + u8 _wordsz; /* # bytes containing rel fld */
2438 + u8 _dum1;
2439 + u16 _dum2;
2440 + u16 _type;
2441 +#else
2442 + unsigned _dum1:8;
2443 + unsigned _wordsz:8; /* # bytes containing rel fld */
2444 + unsigned _fieldsz:8; /* size of rel fld */
2445 + unsigned _offset:8; /* bit offset of rel fld */
2446 + u16 _type;
2447 + u16 _dum2;
2448 +#endif
2449 + } _r_field;
2451 + struct {
2452 + u32 _spc; /* image packet relative PC */
2453 +#ifndef _BIG_ENDIAN
2454 + u16 _dum;
2455 + u16 _type; /* relocation type */
2456 +#else
2457 + u16 _type; /* relocation type */
2458 + u16 _dum;
2459 +#endif
2460 + } _r_spc;
2462 + struct {
2463 + u32 _uval; /* constant value */
2464 +#ifndef _BIG_ENDIAN
2465 + u16 _dum;
2466 + u16 _type; /* relocation type */
2467 +#else
2468 + u16 _type; /* relocation type */
2469 + u16 _dum;
2470 +#endif
2471 + } _r_uval;
2473 + struct {
2474 + s32 _symndx; /* 32-bit sym tbl index */
2475 +#ifndef _BIG_ENDIAN
2476 + u16 _disp; /* extra addr encode data */
2477 + u16 _type; /* relocation type */
2478 +#else
2479 + u16 _type; /* relocation type */
2480 + u16 _disp; /* extra addr encode data */
2481 +#endif
2482 + } _r_sym;
2483 + } _u_reloc;
2485 +} ;
2487 +/* abbreviations for convenience */
2488 +#ifndef r_type
2489 +#define r_type _u_reloc._r_sym._type
2490 +#define r_uval _u_reloc._r_uval._uval
2491 +#define r_symndx _u_reloc._r_sym._symndx
2492 +#define r_offset _u_reloc._r_field._offset
2493 +#define r_fieldsz _u_reloc._r_field._fieldsz
2494 +#define r_wordsz _u_reloc._r_field._wordsz
2495 +#define r_disp _u_reloc._r_sym._disp
2496 +#endif
2498 +/*****************************************************************************/
2499 +/* */
2500 +/* Important DOFF macros used for file processing */
2501 +/* */
2502 +/*****************************************************************************/
2504 +/* DOFF Versions */
2505 +#define DOFF0 0
2507 +/* Return the address/size >= to addr that is at a 32-bit boundary */
2508 +/* This assumes that a byte is 8 bits */
2509 +#define DOFF_ALIGN(addr) (((addr) + 3) & ~UINT32_C(3))
2511 +/*****************************************************************************/
2512 +/* */
2513 +/* The DOFF section header flags field is laid out as follows: */
2514 +/* */
2515 +/* Bits 0-3 : Section Type */
2516 +/* Bit 4 : Set when section requires target memory to be allocated by DL */
2517 +/* Bit 5 : Set when section requires downloading */
2518 +/* Bits 8-11: Alignment, same as COFF */
2519 +/* */
2520 +/*****************************************************************************/
2522 +/* Enum for DOFF section types (bits 0-3 of flag): See dynamic_loader.h */
2524 +/* Macros to help processing of sections */
2525 +#define DLOAD_SECT_TYPE(s_hdr) ((s_hdr)->ds_flags & 0xF)
2527 +/* DS_ALLOCATE indicates whether a section needs space on the target */
2528 +#define DS_ALLOCATE_MASK 0x10
2529 +#define DS_NEEDS_ALLOCATION(s_hdr) ((s_hdr)->ds_flags & DS_ALLOCATE_MASK)
2531 +/* DS_DOWNLOAD indicates that the loader needs to copy bits */
2532 +#define DS_DOWNLOAD_MASK 0x20
2533 +#define DS_NEEDS_DOWNLOAD(s_hdr) ((s_hdr)->ds_flags & DS_DOWNLOAD_MASK)
2535 +/* Section alignment requirement in AUs */
2536 +#define DS_ALIGNMENT(ds_flags) (1 << (((ds_flags) >> 8) & 0xF))
2538 +#endif /* _DOFF_H */
2539 Index: lk/drivers/dsp/bridge/dynload/getsection.c
2540 ===================================================================
2541 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2542 +++ lk/drivers/dsp/bridge/dynload/getsection.c 2008-08-18 10:38:35.000000000 +0300
2543 @@ -0,0 +1,412 @@
2545 + * linux/drivers/dsp/bridge/dynload/getsection.c
2547 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
2549 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
2551 + * This package is free software; you can redistribute it and/or modify
2552 + * it under the terms of the GNU General Public License version 2 as
2553 + * published by the Free Software Foundation.
2555 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2556 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2557 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2558 + */
2562 +#include "getsection.h"
2563 +#include "header.h"
2566 + * Error strings
2567 + */
2568 +static const char E_READSTRM[] = { "Error reading %s from input stream" };
2569 +static const char E_SEEK[] = { "Set file position to %d failed" };
2570 +static const char E_ISIZ[] = { "Bad image packet size %d" };
2571 +static const char E_CHECKSUM[] = { "Checksum failed on %s" };
2572 +static const char E_RELOC[] = { "DLOAD_GetSection unable to read"
2573 + "sections containing relocation entries"};
2574 +#if BITS_PER_AU > BITS_PER_BYTE
2575 +static const char E_ALLOC[] = { "Syms->Allocate( %d ) failed" };
2576 +static const char E_STBL[] = { "Bad string table offset " FMT_UI32 };
2577 +#endif
2580 + * we use the fact that DOFF section records are shaped just like
2581 + * LDR_SECTION_INFO to reduce our section storage usage. These macros
2582 + * marks the places where that assumption is made
2583 + */
2584 +#define DOFFSEC_IS_LDRSEC(pdoffsec) ((struct LDR_SECTION_INFO *)(pdoffsec))
2585 +#define LDRSEC_IS_DOFFSEC(ldrsec) ((struct doff_scnhdr_t *)(ldrsec))
2587 +/***************************************************************/
2588 +/********************* SUPPORT FUNCTIONS ***********************/
2589 +/***************************************************************/
2591 +#if BITS_PER_AU > BITS_PER_BYTE
2592 +/**************************************************************************
2593 + * Procedure unpack_sec_name
2595 + * Parameters:
2596 + * dlthis Handle from DLOAD_module_open for this module
2597 + * soffset Byte offset into the string table
2598 + * dst Place to store the expanded string
2600 + * Effect:
2601 + * Stores a string from the string table into the destination, expanding
2602 + * it in the process. Returns a pointer just past the end of the stored
2603 + * string on success, or NULL on failure.
2605 + *************************************************************************/
2606 +static char *unpack_sec_name(struct dload_state *dlthis,
2607 + u32 soffset, char *dst)
2609 + u8 tmp, *src;
2611 + if (soffset >= dlthis->dfile_hdr.df_scn_name_size) {
2612 + dload_error(dlthis, E_STBL, soffset);
2613 + return NULL;
2615 + src = (u8 *)dlthis->str_head +
2616 + (soffset >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE));
2617 + if (soffset & 1)
2618 + *dst++ = *src++; /* only 1 character in first word */
2619 + do {
2620 + tmp = *src++;
2621 + *dst = (tmp >> BITS_PER_BYTE)
2622 + if (!(*dst++))
2623 + break;
2624 + } while ((*dst++ = tmp & BYTE_MASK));
2626 + return dst;
2629 +/**************************************************************************
2630 + * Procedure expand_sec_names
2632 + * Parameters:
2633 + * dlthis Handle from DLOAD_module_open for this module
2635 + * Effect:
2636 + * Allocates a buffer, unpacks and copies strings from string table into it.
2637 + * Stores a pointer to the buffer into a state variable.
2638 + **************************************************************************/
2639 +static void expand_sec_names(struct dload_state *dlthis)
2641 + char *xstrings, *curr, *next;
2642 + u32 xsize;
2643 + u16 sec;
2644 + struct LDR_SECTION_INFO *shp;
2645 + /* assume worst-case size requirement */
2646 + xsize = dlthis->dfile_hdr.df_max_str_len * dlthis->dfile_hdr.df_no_scns;
2647 + xstrings = (char *)dlthis->mysym->Allocate(dlthis->mysym, xsize);
2648 + if (xstrings == NULL) {
2649 + dload_error(dlthis, E_ALLOC, xsize);
2650 + return;
2652 + dlthis->xstrings = xstrings;
2653 + /* For each sec, copy and expand its name */
2654 + curr = xstrings;
2655 + for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
2656 + shp = DOFFSEC_IS_LDRSEC(&dlthis->sect_hdrs[sec]);
2657 + next = unpack_sec_name(dlthis, *(u32 *) &shp->name, curr);
2658 + if (next == NULL)
2659 + break; /* error */
2660 + shp->name = curr;
2661 + curr = next;
2665 +#endif
2667 +/***************************************************************/
2668 +/********************* EXPORTED FUNCTIONS **********************/
2669 +/***************************************************************/
2671 +/**************************************************************************
2672 + * Procedure DLOAD_module_open
2674 + * Parameters:
2675 + * module The input stream that supplies the module image
2676 + * syms Host-side malloc/free and error reporting functions.
2677 + * Other methods are unused.
2679 + * Effect:
2680 + * Reads header information from a dynamic loader module using the
2681 + specified
2682 + * stream object, and returns a handle for the module information. This
2683 + * handle may be used in subsequent query calls to obtain information
2684 + * contained in the module.
2686 + * Returns:
2687 + * NULL if an error is encountered, otherwise a module handle for use
2688 + * in subsequent operations.
2689 + **************************************************************************/
2690 +DLOAD_module_info DLOAD_module_open(struct Dynamic_Loader_Stream *module,
2691 + struct Dynamic_Loader_Sym *syms)
2693 + struct dload_state *dlthis; /* internal state for this call */
2694 + unsigned *dp, sz;
2695 + u32 sec_start;
2696 +#if BITS_PER_AU <= BITS_PER_BYTE
2697 + u16 sec;
2698 +#endif
2700 + /* Check that mandatory arguments are present */
2701 + if (!module || !syms) {
2702 + if (syms != 0)
2703 + dload_syms_error(syms, "Required parameter is NULL");
2705 + return NULL;
2708 + dlthis = (struct dload_state *)
2709 + syms->Allocate(syms, sizeof(struct dload_state));
2710 + if (!dlthis) {
2711 + /* not enough storage */
2712 + dload_syms_error(syms, "Can't allocate module info");
2713 + return NULL;
2716 + /* clear our internal state */
2717 + dp = (unsigned *)dlthis;
2718 + for (sz = sizeof(struct dload_state) / sizeof(unsigned);
2719 + sz > 0; sz -= 1)
2720 + *dp++ = 0;
2722 + dlthis->strm = module;
2723 + dlthis->mysym = syms;
2725 + /* read in the doff image and store in our state variable */
2726 + dload_headers(dlthis);
2728 + if (!dlthis->dload_errcount)
2729 + dload_strings(dlthis, true);
2731 + /* skip ahead past the unread portion of the string table */
2732 + sec_start = sizeof(struct doff_filehdr_t) +
2733 + sizeof(struct doff_verify_rec_t) +
2734 + BYTE_TO_HOST(DOFF_ALIGN(dlthis->dfile_hdr.df_strtab_size));
2736 + if (dlthis->strm->set_file_posn(dlthis->strm, sec_start) != 0) {
2737 + dload_error(dlthis, E_SEEK, sec_start);
2738 + return NULL;
2741 + if (!dlthis->dload_errcount)
2742 + dload_sections(dlthis);
2744 + if (dlthis->dload_errcount) {
2745 + DLOAD_module_close(dlthis); /* errors, blow off our state */
2746 + dlthis = NULL;
2747 + return NULL;
2749 +#if BITS_PER_AU > BITS_PER_BYTE
2750 + /* Expand all section names from the string table into the */
2751 + /* state variable, and convert section names from a relative */
2752 + /* string table offset to a pointers to the expanded string. */
2753 + expand_sec_names(dlthis);
2754 +#else
2755 + /* Convert section names from a relative string table offset */
2756 + /* to a pointer into the string table. */
2757 + for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
2758 + struct LDR_SECTION_INFO *shp =
2759 + DOFFSEC_IS_LDRSEC(&dlthis->sect_hdrs[sec]);
2760 + shp->name = dlthis->str_head + *(u32 *)&shp->name;
2762 +#endif
2764 + return dlthis;
2767 +/***************************************************************************
2768 + * Procedure DLOAD_GetSectionInfo
2770 + * Parameters:
2771 + * minfo Handle from DLOAD_module_open for this module
2772 + * sectionName Pointer to the string name of the section desired
2773 + * sectionInfo Address of a section info structure pointer to be
2774 + * initialized
2776 + * Effect:
2777 + * Finds the specified section in the module information, and initializes
2778 + * the provided struct LDR_SECTION_INFO pointer.
2780 + * Returns:
2781 + * true for success, false for section not found
2782 + **************************************************************************/
2783 +int DLOAD_GetSectionInfo(DLOAD_module_info minfo, const char *sectionName,
2784 + const struct LDR_SECTION_INFO **const sectionInfo)
2786 + struct dload_state *dlthis;
2787 + struct LDR_SECTION_INFO *shp;
2788 + u16 sec;
2790 + dlthis = (struct dload_state *)minfo;
2791 + if (!dlthis)
2792 + return false;
2794 + for (sec = 0; sec < dlthis->dfile_hdr.df_no_scns; sec++) {
2795 + shp = DOFFSEC_IS_LDRSEC(&dlthis->sect_hdrs[sec]);
2796 + if (strcmp(sectionName, shp->name) == 0) {
2797 + *sectionInfo = shp;
2798 + return true;
2802 + return false;
2805 +#define IPH_SIZE (sizeof(struct image_packet_t) - sizeof(u32))
2806 +#define REVERSE_REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303)
2808 +/**************************************************************************
2809 + * Procedure DLOAD_GetSection
2811 + * Parameters:
2812 + * minfo Handle from DLOAD_module_open for this module
2813 + * sectionInfo Pointer to a section info structure for the desired
2814 + * section
2815 + * sectionData Buffer to contain the section initialized data
2817 + * Effect:
2818 + * Copies the initialized data for the specified section into the
2819 + * supplied buffer.
2821 + * Returns:
2822 + * true for success, false for section not found
2823 + **************************************************************************/
2824 +int DLOAD_GetSection(DLOAD_module_info minfo,
2825 + const struct LDR_SECTION_INFO *sectionInfo, void *sectionData)
2827 + struct dload_state *dlthis;
2828 + u32 pos;
2829 + struct doff_scnhdr_t *sptr = NULL;
2830 + s32 nip;
2831 + struct image_packet_t ipacket;
2832 + s32 ipsize;
2833 + u32 checks;
2834 + s8 *dest = (s8 *)sectionData;
2836 + dlthis = (struct dload_state *)minfo;
2837 + if (!dlthis)
2838 + return false;
2839 + sptr = LDRSEC_IS_DOFFSEC(sectionInfo);
2840 + if (sptr == NULL)
2841 + return false;
2843 + /* skip ahead to the start of the first packet */
2844 + pos = BYTE_TO_HOST(DOFF_ALIGN((u32) sptr->ds_first_pkt_offset));
2845 + if (dlthis->strm->set_file_posn(dlthis->strm, pos) != 0) {
2846 + dload_error(dlthis, E_SEEK, pos);
2847 + return false;
2850 + nip = sptr->ds_nipacks;
2851 + while ((nip -= 1) >= 0) { /* for each packet */
2852 + /* get the fixed header bits */
2853 + if (dlthis->strm->
2854 + read_buffer(dlthis->strm, &ipacket, IPH_SIZE) != IPH_SIZE) {
2855 + dload_error(dlthis, E_READSTRM, "image packet");
2856 + return false;
2858 + /* reorder the header if need be */
2859 + if (dlthis->reorder_map)
2860 + dload_reorder(&ipacket, IPH_SIZE, dlthis->reorder_map);
2862 + /* Now read the packet image bits. Note: round the size up to
2863 + * the next multiple of 4 bytes; this is what checksum
2864 + * routines want. */
2865 + ipsize = BYTE_TO_HOST(DOFF_ALIGN(ipacket.i_packet_size));
2866 + if (ipsize > BYTE_TO_HOST(IMAGE_PACKET_SIZE)) {
2867 + dload_error(dlthis, E_ISIZ, ipsize);
2868 + return false;
2870 + if (dlthis->strm->read_buffer
2871 + (dlthis->strm, dest, ipsize) != ipsize) {
2872 + dload_error(dlthis, E_READSTRM, "image packet");
2873 + return false;
2875 + /* reorder the bytes if need be */
2876 +#if !defined(_BIG_ENDIAN) || (TARGET_AU_BITS > 16)
2877 + if (dlthis->reorder_map)
2878 + dload_reorder(dest, ipsize, dlthis->reorder_map);
2880 + checks = dload_checksum(dest, ipsize);
2881 +#else
2882 + if (dlthis->dfile_hdr.df_byte_reshuffle !=
2883 + TARGET_ORDER(REORDER_MAP(BYTE_RESHUFFLE_VALUE))) {
2884 + /* put image bytes in big-endian order, not PC order */
2885 + dload_reorder(dest, ipsize,
2886 + TARGET_ORDER(dlthis->dfile_hdr.
2887 + df_byte_reshuffle));
2889 +#if TARGET_AU_BITS > 8
2890 + checks = dload_reverse_checksum_16(dest, ipsize);
2891 +#else
2892 + checks = dload_reverse_checksum(dest, ipsize);
2893 +#endif
2894 +#endif
2895 + checks += dload_checksum(&ipacket, IPH_SIZE);
2897 + /* NYI: unable to handle relocation entries here. Reloc
2898 + * entries referring to fields that span the packet boundaries
2899 + * may result in packets of sizes that are not multiple of
2900 + * 4 bytes. Our checksum implementation works on 32-bit words
2901 + * only. */
2902 + if (ipacket.i_num_relocs != 0) {
2903 + dload_error(dlthis, E_RELOC, ipsize);
2904 + return false;
2907 + if (~checks) {
2908 + dload_error(dlthis, E_CHECKSUM, "image packet");
2909 + return false;
2912 + /*Advance destination ptr by the size of the just-read packet*/
2913 + dest += ipsize;
2916 + return true;
2919 +/***************************************************************************
2920 + * Procedure DLOAD_module_close
2922 + * Parameters:
2923 + * minfo Handle from DLOAD_module_open for this module
2925 + * Effect:
2926 + * Releases any storage associated with the module handle. On return,
2927 + * the module handle is invalid.
2929 + * Returns:
2930 + * Zero for success. On error, the number of errors detected is returned.
2931 + * Individual errors are reported using syms->Error_Report(), where syms was
2932 + * an argument to DLOAD_module_open
2933 + **************************************************************************/
2934 +void DLOAD_module_close(DLOAD_module_info minfo)
2936 + struct dload_state *dlthis;
2938 + dlthis = (struct dload_state *)minfo;
2939 + if (!dlthis)
2940 + return;
2942 + if (dlthis->str_head)
2943 + dlthis->mysym->Deallocate(dlthis->mysym, dlthis->str_head);
2945 + if (dlthis->sect_hdrs)
2946 + dlthis->mysym->Deallocate(dlthis->mysym, dlthis->sect_hdrs);
2948 +#if BITS_PER_AU > BITS_PER_BYTE
2949 + if (dlthis->xstrings)
2950 + dlthis->mysym->Deallocate(dlthis->mysym, dlthis->xstrings);
2952 +#endif
2954 + dlthis->mysym->Deallocate(dlthis->mysym, dlthis);
2956 Index: lk/drivers/dsp/bridge/dynload/header.h
2957 ===================================================================
2958 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2959 +++ lk/drivers/dsp/bridge/dynload/header.h 2008-08-18 10:38:35.000000000 +0300
2960 @@ -0,0 +1,59 @@
2962 + * linux/drivers/dsp/bridge/dynload/header.h
2964 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
2966 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
2968 + * This package is free software; you can redistribute it and/or modify
2969 + * it under the terms of the GNU General Public License version 2 as
2970 + * published by the Free Software Foundation.
2972 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
2973 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
2974 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2975 + */
2979 +#define TRUE 1
2980 +#define FALSE 0
2981 +#ifndef NULL
2982 +#define NULL 0
2983 +#endif
2985 +#include <linux/string.h>
2986 +#define DL_STRCMP strcmp
2988 +/* maximum parenthesis nesting in relocation stack expressions */
2989 +#define STATIC_EXPR_STK_SIZE 10
2991 +#include <linux/types.h>
2992 +typedef unsigned int uint_least32_t;
2993 +typedef unsigned short int uint_least16_t;
2995 +#include "doff.h"
2996 +#include "dynamic_loader.h"
2997 +#include "params.h"
2998 +#include "dload_internal.h"
2999 +#include "reloc_table.h"
3002 + * Plausibility limits
3004 + * These limits are imposed upon the input DOFF file as a check for validity.
3005 + * They are hard limits, in that the load will fail if they are exceeded.
3006 + * The numbers selected are arbitrary, in that the loader implementation does
3007 + * not require these limits.
3008 + */
3010 +/* maximum number of bytes in string table */
3011 +#define MAX_REASONABLE_STRINGTAB (0x100000)
3012 +/* maximum number of code,data,etc. sections */
3013 +#define MAX_REASONABLE_SECTIONS (200)
3014 +/* maximum number of linker symbols */
3015 +#define MAX_REASONABLE_SYMBOLS (100000)
3017 +/* shift count to align F_BIG with DLOAD_LITTLE */
3018 +#define ALIGN_COFF_ENDIANNESS 7
3019 +#define ENDIANNESS_MASK (DF_BYTE_ORDER >> ALIGN_COFF_ENDIANNESS)
3020 Index: lk/drivers/dsp/bridge/dynload/module_list.h
3021 ===================================================================
3022 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3023 +++ lk/drivers/dsp/bridge/dynload/module_list.h 2008-08-18 10:38:35.000000000 +0300
3024 @@ -0,0 +1,161 @@
3026 + * dspbridge/mpu_driver/src/dynload/module_list.h
3028 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3030 + * Copyright (C) 2008 Texas Instruments, Inc.
3032 + * This package is free software; you can redistribute it and/or modify
3033 + * it under the terms of the GNU General Public License version 2 as
3034 + * published by the Free Software Foundation.
3036 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3037 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3038 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3039 + */
3041 +/*============================================================================
3042 + Filename: module_list.h
3044 + Copyright (C) 2002 Texas Instruments Incorporated
3047 + This C header file gives the layout of the data structure created by the
3048 + dynamic loader to describe the set of modules loaded into the DSP.
3050 + Linked List Structure:
3051 + ----------------------
3052 + The data structure defined here is a singly-linked list. The list
3053 + represents the set of modules which are currently loaded in the DSP memory.
3054 + The first entry in the list is a header record which contains a flag
3055 + representing the state of the list. The rest of the entries in the list
3056 + are module records.
3058 + Global symbol _DLModules designates the first record in the list (i.e. the
3059 + header record). This symbol must be defined in any program that wishes to
3060 + use DLLview plug-in.
3062 + String Representation:
3063 + ----------------------
3064 + The string names of the module and its sections are stored in a block of
3065 + memory which follows the module record itself. The strings are ordered:
3066 + module name first, followed by section names in order from the first
3067 + section to the last. String names are tightly packed arrays of 8-bit
3068 + characters (two characters per 16-bit word on the C55x). Strings are
3069 + zero-byte-terminated.
3071 + Creating and updating the list:
3072 +-------------------------------
3073 + Upon loading a new module into the DSP memory the dynamic loader inserts a
3074 +new module record as the first module record in the list. The fields of
3075 + this module record are initialized to reflect the properties of the module.
3076 + The dynamic loader does NOT increment the flag/counter in the list's header
3077 + record.
3079 + Upon unloading a module from the DSP memory the dynamic loader removes the
3080 +module's record from this list. The dynamic loader also increments the
3081 + flag/counter in the list's header record to indicate that the list has been
3082 + changed.
3084 +============================================================================*/
3086 +#ifndef _MODULE_LIST_H_
3087 +#define _MODULE_LIST_H_
3089 +#include <linux/types.h>
3091 +/* Global pointer to the modules_header structure*/
3092 +#define MODULES_HEADER "_DLModules"
3093 +#define MODULES_HEADER_NO_UNDERSCORE "DLModules"
3095 +/* Initial version number*/
3096 +#define INIT_VERSION 1
3098 +/* Verification number -- to be recorded in each module record */
3099 +#define VERIFICATION 0x79
3101 +/* forward declarations */
3102 +struct dll_module;
3103 +struct dll_sect;
3105 +/* the first entry in the list is the modules_header record;
3106 + * its address is contained in the global _DLModules pointer */
3107 +struct modules_header {
3109 + /* Address of the first dll_module record in the list or NULL.
3110 + Note: for C55x this is a word address (C55x data is word-addressable)*/
3111 + u32 first_module;
3113 + /* Combined storage size (in target addressable units) of the
3114 + * dll_module record which follows this header record, or zero
3115 + * if the list is empty. This size includes the module's string table.
3116 + * Note: for C55x the unit is a 16-bit word */
3117 + u16 first_module_size;
3119 + /* Counter is incremented whenever a module record is removed from
3120 + * the list */
3121 + u16 update_flag;
3123 +} ;
3125 +/* for each 32-bits in above structure, a bitmap, LSB first, whose bits are:
3126 + * 0 => a 32-bit value, 1 => 2 16-bit values */
3127 +#define MODULES_HEADER_BITMAP 0x2 /* swapping bitmap for type modules_header */
3129 +/* information recorded about each section in a module */
3130 +struct dll_sect {
3132 + /* Load-time address of the section.
3133 + * Note: for C55x this is a byte address for program sections, and
3134 + * a word address for data sections. C55x program memory is
3135 + * byte-addressable, while data memory is word-addressable. */
3136 + u32 sect_load_adr;
3138 + /* Run-time address of the section.
3139 + * Note 1: for C55x this is a byte address for program sections, and
3140 + * a word address for data sections.
3141 + * Note 2: for C55x two most significant bits of this field indicate
3142 + * the section type: '00' for a code section, '11' for a data section
3143 + * (C55 addresses are really only 24-bits wide). */
3144 + u32 sect_run_adr;
3146 +} ;
3148 +/* the rest of the entries in the list are module records */
3149 +struct dll_module {
3151 + /* Address of the next dll_module record in the list, or 0 if this is
3152 + * the last record in the list.
3153 + * Note: for C55x this is a word address (C55x data is
3154 + * word-addressable) */
3155 + u32 next_module;
3157 + /* Combined storage size (in target addressable units) of the
3158 + * dll_module record which follows this one, or zero if this is the
3159 + * last record in the list. This size includes the module's string
3160 + * table.
3161 + * Note: for C55x the unit is a 16-bit word. */
3162 + u16 next_module_size;
3164 + /* version number of the tooling; set to INIT_VERSION for Phase 1 */
3165 + u16 version;
3167 + /* the verification word; set to VERIFICATION */
3168 + u16 verification;
3170 + /* Number of sections in the sects array */
3171 + u16 num_sects;
3173 + /* Module's "unique" id; copy of the timestamp from the host
3174 + * COFF file */
3175 + u32 timestamp;
3177 + /* Array of num_sects elements of the module's section records */
3178 + struct dll_sect sects[1];
3179 +} ;
3181 +/* for each 32 bits in above structure, a bitmap, LSB first, whose bits are:
3182 + * 0 => a 32-bit value, 1 => 2 16-bit values */
3183 +#define DLL_MODULE_BITMAP 0x6 /* swapping bitmap for type dll_module */
3185 +#endif /* _MODULE_LIST_H_ */
3186 Index: lk/drivers/dsp/bridge/dynload/params.h
3187 ===================================================================
3188 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3189 +++ lk/drivers/dsp/bridge/dynload/params.h 2008-08-18 10:38:35.000000000 +0300
3190 @@ -0,0 +1,231 @@
3192 + * linux/drivers/dsp/bridge/dynload/params.h
3194 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3196 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
3198 + * This package is free software; you can redistribute it and/or modify
3199 + * it under the terms of the GNU General Public License version 2 as
3200 + * published by the Free Software Foundation.
3202 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3203 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3204 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3205 + */
3209 +/******************************************************************************
3211 + * This file defines host and target properties for all machines
3212 + * supported by the dynamic loader. To be tedious...
3214 + * host == the machine on which the dynamic loader runs
3215 + * target == the machine that the dynamic loader is loading
3217 + * Host and target may or may not be the same, depending upon the particular
3218 + * use.
3219 + *****************************************************************************/
3221 +/******************************************************************************
3223 + * Host Properties
3225 + *****************************************************************************/
3227 +#define BITS_PER_BYTE 8 /* bits in the standard PC/SUN byte */
3228 +#define LOG_BITS_PER_BYTE 3 /* log base 2 of same */
3229 +#define BYTE_MASK ((1U<<BITS_PER_BYTE)-1)
3231 +#if defined(__TMS320C55X__) || defined(_TMS320C5XX)
3232 +#define BITS_PER_AU 16
3233 +#define LOG_BITS_PER_AU 4
3234 + /* use this print string in error messages for uint32_t */
3235 +#define FMT_UI32 "0x%lx"
3236 +#define FMT8_UI32 "%08lx" /* same but no 0x, fixed width field */
3237 +#else
3238 +#define BITS_PER_AU 8 /* bits in the smallest addressable data storage unit */
3239 +#define LOG_BITS_PER_AU 3 /* log base 2 of the same; useful for shift counts */
3240 +#define FMT_UI32 "0x%x"
3241 +#define FMT8_UI32 "%08x"
3242 +#endif
3244 +/* generic fastest method for swapping bytes and shorts */
3245 +#define SWAP32BY16(zz) (((zz) << 16) | ((zz) >> 16))
3246 +#define SWAP16BY8(zz) (((zz) << 8) | ((zz) >> 8))
3248 +/* !! don't be tempted to insert type definitions here; use <stdint.h> !! */
3250 +/******************************************************************************
3252 + * Target Properties
3254 + *****************************************************************************/
3257 +/*--------------------------------------------------------------------------*/
3258 +/* TMS320C6x Target Specific Parameters (byte-addressable) */
3259 +/*--------------------------------------------------------------------------*/
3260 +#if TMS32060
3261 +#define MEMORG 0x0L /* Size of configured memory */
3262 +#define MEMSIZE 0x0L /* (full address space) */
3264 +#define CINIT_ALIGN 8 /* alignment of cinit record in TDATA AUs */
3265 +#define CINIT_COUNT 4 /* width of count field in TDATA AUs */
3266 +#define CINIT_ADDRESS 4 /* width of address field in TDATA AUs */
3267 +#define CINIT_PAGE_BITS 0 /* Number of LSBs of address that
3268 + * are page number */
3270 +#define LENIENT_SIGNED_RELEXPS 0 /* DOES SIGNED ALLOW MAX UNSIGNED */
3272 +#undef TARGET_ENDIANNESS /* may be big or little endian */
3274 +/* align a target address to a word boundary */
3275 +#define TARGET_WORD_ALIGN(zz) (((zz) + 0x3) & -0x4)
3276 +#endif
3279 +/*--------------------------------------------------------------------------
3281 + * DEFAULT SETTINGS and DERIVED PROPERTIES
3283 + * This section establishes defaults for values not specified above
3284 + *--------------------------------------------------------------------------*/
3285 +#ifndef TARGET_AU_BITS
3286 +#define TARGET_AU_BITS 8 /* width of the target addressable unit */
3287 +#define LOG_TARGET_AU_BITS 3 /* log2 of same */
3288 +#endif
3290 +#ifndef CINIT_DEFAULT_PAGE
3291 +#define CINIT_DEFAULT_PAGE 0 /* default .cinit page number */
3292 +#endif
3294 +#ifndef DATA_RUN2LOAD
3295 +#define DATA_RUN2LOAD(zz) (zz) /* translate data run address to load address */
3296 +#endif
3298 +#ifndef DBG_LIST_PAGE
3299 +#define DBG_LIST_PAGE 0 /* page number for .dllview section */
3300 +#endif
3302 +#ifndef TARGET_WORD_ALIGN
3303 +/* align a target address to a word boundary */
3304 +#define TARGET_WORD_ALIGN(zz) (zz)
3305 +#endif
3307 +#ifndef TDATA_TO_TADDR
3308 +#define TDATA_TO_TADDR(zz) (zz) /* target data address to target AU address */
3309 +#define TADDR_TO_TDATA(zz) (zz) /* target AU address to target data address */
3310 +#define TDATA_AU_BITS TARGET_AU_BITS /* bits per data AU */
3311 +#define LOG_TDATA_AU_BITS LOG_TARGET_AU_BITS
3312 +#endif
3316 + * Useful properties and conversions derived from the above
3318 + */
3321 + * Conversions between host and target addresses
3322 + */
3323 +#if LOG_BITS_PER_AU == LOG_TARGET_AU_BITS
3324 +/* translate target addressable unit to host address */
3325 +#define TADDR_TO_HOST(x) (x)
3326 +/* translate host address to target addressable unit */
3327 +#define HOST_TO_TADDR(x) (x)
3328 +#elif LOG_BITS_PER_AU > LOG_TARGET_AU_BITS
3329 +#define TADDR_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS))
3330 +#define HOST_TO_TADDR(x) ((x) << (LOG_BITS_PER_AU-LOG_TARGET_AU_BITS))
3331 +#else
3332 +#define TADDR_TO_HOST(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU))
3333 +#define HOST_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_AU))
3334 +#endif
3336 +#if LOG_BITS_PER_AU == LOG_TDATA_AU_BITS
3337 +/* translate target addressable unit to host address */
3338 +#define TDATA_TO_HOST(x) (x)
3339 +/* translate host address to target addressable unit */
3340 +#define HOST_TO_TDATA(x) (x)
3341 +/* translate host address to target addressable unit, round up */
3342 +#define HOST_TO_TDATA_ROUND(x) (x)
3343 +/* byte offset to host offset, rounded up for TDATA size */
3344 +#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x)
3345 +#elif LOG_BITS_PER_AU > LOG_TDATA_AU_BITS
3346 +#define TDATA_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
3347 +#define HOST_TO_TDATA(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
3348 +#define HOST_TO_TDATA_ROUND(x) ((x) << (LOG_BITS_PER_AU-LOG_TDATA_AU_BITS))
3349 +#define BYTE_TO_HOST_TDATA_ROUND(x) BYTE_TO_HOST_ROUND(x)
3350 +#else
3351 +#define TDATA_TO_HOST(x) ((x) << (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
3352 +#define HOST_TO_TDATA(x) ((x) >> (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
3353 +#define HOST_TO_TDATA_ROUND(x) (((x) +\
3354 + (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))-1) >>\
3355 + (LOG_TDATA_AU_BITS-LOG_BITS_PER_AU))
3356 +#define BYTE_TO_HOST_TDATA_ROUND(x) (BYTE_TO_HOST((x) +\
3357 + (1<<(LOG_TDATA_AU_BITS-LOG_BITS_PER_BYTE))-1) &\
3358 + -(TDATA_AU_BITS/BITS_PER_AU))
3359 +#endif
3362 + * Input in DOFF format is always expresed in bytes, regardless of loading host
3363 + * so we wind up converting from bytes to target and host units even when the
3364 + * host is not a byte machine.
3365 + */
3366 +#if LOG_BITS_PER_AU == LOG_BITS_PER_BYTE
3367 +#define BYTE_TO_HOST(x) (x)
3368 +#define BYTE_TO_HOST_ROUND(x) (x)
3369 +#define HOST_TO_BYTE(x) (x)
3370 +#elif LOG_BITS_PER_AU >= LOG_BITS_PER_BYTE
3371 +#define BYTE_TO_HOST(x) ((x) >> (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
3372 +#define BYTE_TO_HOST_ROUND(x) ((x + (BITS_PER_AU/BITS_PER_BYTE-1)) >>\
3373 + (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
3374 +#define HOST_TO_BYTE(x) ((x) << (LOG_BITS_PER_AU - LOG_BITS_PER_BYTE))
3375 +#else
3376 +/* lets not try to deal with sub-8-bit byte machines */
3377 +#endif
3379 +#if LOG_TARGET_AU_BITS == LOG_BITS_PER_BYTE
3380 +/* translate target addressable unit to byte address */
3381 +#define TADDR_TO_BYTE(x) (x)
3382 +/* translate byte address to target addressable unit */
3383 +#define BYTE_TO_TADDR(x) (x)
3384 +#elif LOG_TARGET_AU_BITS > LOG_BITS_PER_BYTE
3385 +#define TADDR_TO_BYTE(x) ((x) << (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE))
3386 +#define BYTE_TO_TADDR(x) ((x) >> (LOG_TARGET_AU_BITS-LOG_BITS_PER_BYTE))
3387 +#else
3388 +/* lets not try to deal with sub-8-bit byte machines */
3389 +#endif
3391 +#ifdef _BIG_ENDIAN
3392 +#define HOST_ENDIANNESS 1
3393 +#else
3394 +#define HOST_ENDIANNESS 0
3395 +#endif
3397 +#ifdef TARGET_ENDIANNESS
3398 +#define TARGET_ENDIANNESS_DIFFERS(rtend) (HOST_ENDIANNESS^TARGET_ENDIANNESS)
3399 +#elif HOST_ENDIANNESS
3400 +#define TARGET_ENDIANNESS_DIFFERS(rtend) (!(rtend))
3401 +#else
3402 +#define TARGET_ENDIANNESS_DIFFERS(rtend) (rtend)
3403 +#endif
3405 +/* the unit in which we process target image data */
3406 +#if TARGET_AU_BITS <= 8
3407 +typedef u8 TgtAU_t;
3408 +#elif TARGET_AU_BITS <= 16
3409 +typedef u16 TgtAU_t;
3410 +#else
3411 +typedef u32 TgtAU_t;
3412 +#endif
3414 +/* size of that unit */
3415 +#if TARGET_AU_BITS < BITS_PER_AU
3416 +#define TGTAU_BITS BITS_PER_AU
3417 +#define LOG_TGTAU_BITS LOG_BITS_PER_AU
3418 +#else
3419 +#define TGTAU_BITS TARGET_AU_BITS
3420 +#define LOG_TGTAU_BITS LOG_TARGET_AU_BITS
3421 +#endif
3422 Index: lk/drivers/dsp/bridge/dynload/reloc.c
3423 ===================================================================
3424 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3425 +++ lk/drivers/dsp/bridge/dynload/reloc.c 2008-08-18 10:38:35.000000000 +0300
3426 @@ -0,0 +1,425 @@
3428 + * linux/drivers/dsp/bridge/dynload/reloc.c
3430 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3432 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
3434 + * This package is free software; you can redistribute it and/or modify
3435 + * it under the terms of the GNU General Public License version 2 as
3436 + * published by the Free Software Foundation.
3438 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3439 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3440 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3441 + */
3443 +#include "header.h"
3445 +#if TMS32060
3446 +/* the magic symbol for the start of BSS */
3447 +static const char BSSSYMBOL[] = {".bss"};
3448 +#endif
3450 +#if TMS32060
3451 +#include "reloc_table_c6000.c"
3452 +#endif
3454 +#if TMS32060
3455 +/* From coff.h - ignore these relocation operations */
3456 +#define R_C60ALIGN 0x76 /* C60: Alignment info for compressor */
3457 +#define R_C60FPHEAD 0x77 /* C60: Explicit assembly directive */
3458 +#define R_C60NOCMP 0x100 /* C60: Don't compress this code scn */
3459 +#endif
3461 +/**************************************************************************
3462 + * Procedure dload_unpack
3464 + * Parameters:
3465 + * data pointer to storage unit containing lowest host address of
3466 + * image data
3467 + * fieldsz Size of bit field, 0 < fieldsz <= sizeof(RVALUE)*BITS_PER_AU
3468 + * offset Offset from LSB, 0 <= offset < BITS_PER_AU
3469 + * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY)
3471 + * Effect:
3472 + * Extracts the specified field and returns it.
3473 + **************************************************************************/
3474 +RVALUE dload_unpack(struct dload_state *dlthis, TgtAU_t *data, int fieldsz,
3475 + int offset, unsigned sgn)
3477 + register RVALUE objval;
3478 + register int shift, direction;
3479 + register TgtAU_t *dp = data;
3481 + fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value*/
3482 + /* * collect up enough bits to contain the desired field */
3483 + if (TARGET_BIG_ENDIAN) {
3484 + dp += (fieldsz + offset) >> LOG_TGTAU_BITS;
3485 + direction = -1;
3486 + } else
3487 + direction = 1;
3488 + objval = *dp >> offset;
3489 + shift = TGTAU_BITS - offset;
3490 + while (shift <= fieldsz) {
3491 + dp += direction;
3492 + objval += (RVALUE)*dp << shift;
3493 + shift += TGTAU_BITS;
3496 + /* * sign or zero extend the value appropriately */
3497 + if (sgn == ROP_UNS)
3498 + objval &= (2 << fieldsz) - 1;
3499 + else {
3500 + shift = sizeof(RVALUE) * BITS_PER_AU-1 - fieldsz;
3501 + objval = (objval << shift) >> shift;
3504 + return objval;
3506 +} /* dload_unpack */
3509 +/**************************************************************************
3510 + * Procedure dload_repack
3512 + * Parameters:
3513 + * val Value to insert
3514 + * data Pointer to storage unit containing lowest host address of
3515 + * image data
3516 + * fieldsz Size of bit field, 0 < fieldsz <= sizeof(RVALUE)*BITS_PER_AU
3517 + * offset Offset from LSB, 0 <= offset < BITS_PER_AU
3518 + * sgn Signedness of the field (ROP_SGN, ROP_UNS, ROP_MAX, ROP_ANY)
3520 + * Effect:
3521 + * Stuffs the specified value in the specified field. Returns 0 for
3522 + * success
3523 + * or 1 if the value will not fit in the specified field according to the
3524 + * specified signedness rule.
3525 + **************************************************************************/
3526 +static const unsigned char ovf_limit[] = {1, 2, 2};
3527 +int dload_repack(struct dload_state *dlthis, RVALUE val, TgtAU_t *data,
3528 + int fieldsz, int offset, unsigned sgn)
3530 + register URVALUE objval, mask;
3531 + register int shift, direction;
3532 + register TgtAU_t *dp = data;
3535 + fieldsz -= 1; /* avoid nastiness with 32-bit shift of 32-bit value */
3536 + /* clip the bits */
3537 + mask = ((UINT32_C(2) << fieldsz) - 1);
3538 + objval = (val & mask);
3539 + /* * store the bits through the specified mask */
3540 + if (TARGET_BIG_ENDIAN) {
3541 + dp += (fieldsz + offset) >> LOG_TGTAU_BITS;
3542 + direction = -1;
3543 + } else
3544 + direction = 1;
3546 + /* insert LSBs */
3547 + *dp = (*dp & ~(mask << offset)) + (objval << offset);
3548 + shift = TGTAU_BITS-offset;
3549 + /* align mask and objval with AU boundary */
3550 + objval >>= shift;
3551 + mask >>= shift;
3553 + while (mask) {
3554 + dp += direction;
3555 + *dp = (*dp & ~mask) + objval;
3556 + objval >>= TGTAU_BITS;
3557 + mask >>= TGTAU_BITS;
3560 + /*
3561 + * check for overflow
3562 + */
3563 + if (sgn) {
3564 + unsigned tmp = (val >> fieldsz) + (sgn & 0x1);
3565 + if (tmp > ovf_limit[sgn-1])
3566 + return 1;
3568 + return 0;
3570 +} /* dload_repack */
3572 +/* lookup table for the scaling amount in a C6x instruction */
3573 +#if TMS32060
3574 +#define SCALE_BITS 4 /* there are 4 bits in the scale field */
3575 +#define SCALE_MASK 0x7 /* we really only use the bottom 3 bits */
3576 +static const u8 C60_Scale[SCALE_MASK+1] = {
3577 + 1, 0, 0, 0, 1, 1, 2, 2
3579 +#endif
3581 +/**************************************************************************
3582 + * Procedure dload_relocate
3584 + * Parameters:
3585 + * data Pointer to base of image data
3586 + * rp Pointer to relocation operation
3588 + * Effect:
3589 + * Performs the specified relocation operation
3590 + **************************************************************************/
3591 +void dload_relocate(struct dload_state *dlthis, TgtAU_t *data,
3592 + struct reloc_record_t *rp)
3594 + RVALUE val = 0;
3595 + RVALUE reloc_amt = 0;
3596 + unsigned int fieldsz = 0;
3597 + unsigned int offset = 0;
3598 + unsigned int reloc_info = 0;
3599 + unsigned int reloc_action = 0;
3600 + register int rx = 0;
3601 + RVALUE *stackp = NULL;
3602 + int top;
3603 + struct Local_Symbol *svp = NULL;
3604 +#ifdef RFV_SCALE
3605 + unsigned int scale = 0;
3606 +#endif
3608 + rx = HASH_FUNC(rp->r_type);
3609 + while (rop_map1[rx] != rp->r_type) {
3610 + rx = HASH_L(rop_map2[rx]);
3611 + if (rx < 0) {
3612 +#if TMS32060
3613 + switch (rp->r_type) {
3614 + case R_C60ALIGN:
3615 + case R_C60NOCMP:
3616 + case R_C60FPHEAD:
3617 + /* Ignore these reloc types and return */
3618 + break;
3619 + default:
3620 + /* Unknown reloc type, print error and return */
3621 + dload_error(dlthis, "Bad coff operator 0x%x", rp->r_type);
3623 +#else
3624 + dload_error(dlthis, "Bad coff operator 0x%x", rp->r_type);
3625 +#endif
3626 + return;
3629 + rx = HASH_I(rop_map2[rx]);
3630 + if ((rx < (sizeof(rop_action)/sizeof(uint_least16_t)))
3631 + && (rx < (sizeof(rop_info)/sizeof(uint_least16_t))) && (rx > 0)) {
3632 + reloc_action = rop_action[rx]; reloc_info = rop_info[rx];
3633 + } else {
3634 + dload_error(dlthis, "Buffer Overflow - Array Index Out of Bounds");
3637 + /* Compute the relocation amount for the referenced symbol, if any */
3638 + reloc_amt = rp->r_uval;
3639 + if (RFV_SYM(reloc_info)) { /* relocation uses a symbol reference */
3640 + if ((u32)rp->r_symndx < dlthis->dfile_hdr.df_no_syms) {
3641 + /* real symbol reference */
3642 + svp = &dlthis->local_symtab[rp->r_symndx];
3643 + reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ?
3644 + svp->delta : svp->value;
3646 + /* reloc references current section */
3647 + else if (rp->r_symndx == -1)
3648 + reloc_amt = (RFV_SYM(reloc_info) == ROP_SYMD) ?
3649 + dlthis->delta_runaddr : dlthis->image_secn->run_addr;
3650 + } /* relocation uses a symbol reference */
3651 + /* Handle stack adjustment */
3652 + val = 0;
3653 + top = RFV_STK(reloc_info);
3654 + if (top) {
3655 + top += dlthis->relstkidx - RSTK_UOP;
3656 + if (top >= STATIC_EXPR_STK_SIZE) {
3657 + dload_error(dlthis,
3658 + "Expression stack overflow in %s at offset "
3659 + FMT_UI32, dlthis->image_secn->name,
3660 + rp->r_vaddr + dlthis->image_offset);
3661 + return;
3663 + val = dlthis->relstk[dlthis->relstkidx];
3664 + dlthis->relstkidx = top;
3665 + stackp = &dlthis->relstk[top];
3667 + /* Derive field position and size, if we need them */
3668 + if (reloc_info & ROP_RW) { /* read or write action in our future */
3669 + fieldsz = RFV_WIDTH(reloc_action);
3670 + if (fieldsz) { /* field info from table */
3671 + offset = RFV_POSN(reloc_action);
3672 + if (TARGET_BIG_ENDIAN)
3673 + /* make sure r_vaddr is the lowest target
3674 + * address containing bits */
3675 + rp->r_vaddr += RFV_BIGOFF(reloc_info);
3676 + } else { /* field info from relocation op */
3677 + fieldsz = rp->r_fieldsz; offset = rp->r_offset;
3678 + if (TARGET_BIG_ENDIAN)
3679 + /* make sure r_vaddr is the lowest target
3680 + address containing bits */
3681 + rp->r_vaddr += (rp->r_wordsz - offset - fieldsz)
3682 + >> LOG_TARGET_AU_BITS;
3684 + data = (TgtAU_t *)((char *)data + TADDR_TO_HOST(rp->r_vaddr));
3685 + /* compute lowest host location of referenced data */
3686 +#if BITS_PER_AU > TARGET_AU_BITS
3687 + /* conversion from target address to host address may lose
3688 + address bits; add loss to offset */
3689 + if (TARGET_BIG_ENDIAN) {
3690 + offset += -((rp->r_vaddr << LOG_TARGET_AU_BITS) +
3691 + offset + fieldsz) &
3692 + (BITS_PER_AU-TARGET_AU_BITS);
3693 + } else {
3694 + offset += (rp->r_vaddr << LOG_TARGET_AU_BITS) &
3695 + (BITS_PER_AU-1);
3697 +#endif
3698 +#ifdef RFV_SCALE
3699 + scale = RFV_SCALE(reloc_info);
3700 +#endif
3702 + /* read the object value from the current image, if so ordered */
3703 + if (reloc_info & ROP_R) { /* relocation reads current image value */
3704 + val = dload_unpack(dlthis, data, fieldsz, offset,
3705 + RFV_SIGN(reloc_info));
3706 +#ifdef RFV_SCALE
3707 + val <<= scale;
3708 +#endif
3710 + /* perform the necessary arithmetic */
3711 + switch (RFV_ACTION(reloc_action)) { /* relocation actions */
3712 + case RACT_VAL:
3713 + break;
3714 + case RACT_ASGN:
3715 + val = reloc_amt;
3716 + break;
3717 + case RACT_ADD:
3718 + val += reloc_amt;
3719 + break;
3720 + case RACT_PCR:
3721 + /*-----------------------------------------------------------
3722 + * Handle special cases of jumping from absolute sections
3723 + * (special reloc type) or to absolute destination
3724 + * (symndx == -1). In either case, set the appropriate
3725 + * relocation amount to 0.
3726 + *-----------------------------------------------------------*/
3727 + if (rp->r_symndx == -1)
3728 + reloc_amt = 0;
3729 + val += reloc_amt - dlthis->delta_runaddr;
3730 + break;
3731 + case RACT_ADDISP:
3732 + val += rp->r_disp + reloc_amt;
3733 + break;
3734 + case RACT_ASGPC:
3735 + val = dlthis->image_secn->run_addr + reloc_amt;
3736 + break;
3737 + case RACT_PLUS:
3738 + if (stackp != NULL)
3739 + val += *stackp;
3740 + break;
3741 + case RACT_SUB:
3742 + if (stackp != NULL)
3743 + val = *stackp - val;
3744 + break;
3745 + case RACT_NEG:
3746 + val = -val;
3747 + break;
3748 + case RACT_MPY:
3749 + if (stackp != NULL)
3750 + val *= *stackp;
3751 + break;
3752 + case RACT_DIV:
3753 + if (stackp != NULL)
3754 + val = *stackp / val;
3755 + break;
3756 + case RACT_MOD:
3757 + if (stackp != NULL)
3758 + val = *stackp % val;
3759 + break;
3760 + case RACT_SR:
3761 + if (val >= sizeof(RVALUE) * BITS_PER_AU)
3762 + val = 0;
3763 + else if (stackp != NULL)
3764 + val = (URVALUE)*stackp >> val;
3765 + break;
3766 + case RACT_ASR:
3767 + if (val >= sizeof(RVALUE)*BITS_PER_AU)
3768 + val = sizeof(RVALUE)*BITS_PER_AU - 1;
3769 + else if (stackp != NULL)
3770 + val = *stackp >> val;
3771 + break;
3772 + case RACT_SL:
3773 + if (val >= sizeof(RVALUE)*BITS_PER_AU)
3774 + val = 0;
3775 + else if (stackp != NULL)
3776 + val = *stackp << val;
3777 + break;
3778 + case RACT_AND:
3779 + if (stackp != NULL)
3780 + val &= *stackp;
3781 + break;
3782 + case RACT_OR:
3783 + if (stackp != NULL)
3784 + val |= *stackp;
3785 + break;
3786 + case RACT_XOR:
3787 + if (stackp != NULL)
3788 + val ^= *stackp;
3789 + break;
3790 + case RACT_NOT:
3791 + val = ~val;
3792 + break;
3793 +#if TMS32060
3794 + case RACT_C6SECT:
3795 + /* actually needed address of secn containing symbol */
3796 + if (svp != NULL) {
3797 + if (rp->r_symndx >= 0)
3798 + if (svp->secnn > 0)
3799 + reloc_amt = dlthis->ldr_sections
3800 + [svp->secnn-1].run_addr;
3802 + /* !!! FALL THRU !!! */
3803 + case RACT_C6BASE:
3804 + if (dlthis->bss_run_base == 0) {
3805 + struct dynload_symbol *symp;
3806 + symp = dlthis->mysym->Find_Matching_Symbol
3807 + (dlthis->mysym, BSSSYMBOL);
3808 + /* lookup value of global BSS base */
3809 + if (symp)
3810 + dlthis->bss_run_base = symp->value;
3811 + else
3812 + dload_error(dlthis,
3813 + "Global BSS base referenced in %s offset"\
3814 + FMT_UI32 " but not defined",
3815 + dlthis->image_secn->name,
3816 + rp->r_vaddr + dlthis->image_offset);
3818 + reloc_amt -= dlthis->bss_run_base;
3819 + /* !!! FALL THRU !!! */
3820 + case RACT_C6DSPL:
3821 + /* scale factor determined by 3 LSBs of field */
3822 + scale = C60_Scale[val & SCALE_MASK];
3823 + offset += SCALE_BITS;
3824 + fieldsz -= SCALE_BITS;
3825 + val >>= SCALE_BITS; /* ignore the scale field hereafter */
3826 + val <<= scale;
3827 + val += reloc_amt; /* do the usual relocation */
3828 + if (((1 << scale)-1) & val)
3829 + dload_error(dlthis,
3830 + "Unaligned reference in %s offset " FMT_UI32,
3831 + dlthis->image_secn->name,
3832 + rp->r_vaddr + dlthis->image_offset);
3833 + break;
3834 +#endif
3835 + } /* relocation actions */
3836 + /* * Put back result as required */
3837 + if (reloc_info & ROP_W) { /* relocation writes image value */
3838 +#ifdef RFV_SCALE
3839 + val >>= scale;
3840 +#endif
3841 + if (dload_repack(dlthis, val, data, fieldsz, offset,
3842 + RFV_SIGN(reloc_info))) {
3843 + dload_error(dlthis, "Relocation value " FMT_UI32
3844 + " overflows %d bits in %s offset " FMT_UI32, val,
3845 + fieldsz, dlthis->image_secn->name,
3846 + dlthis->image_offset + rp->r_vaddr);
3848 + } else if (top)
3849 + *stackp = val;
3850 +} /* reloc_value */
3852 Index: lk/drivers/dsp/bridge/dynload/reloc_table.h
3853 ===================================================================
3854 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3855 +++ lk/drivers/dsp/bridge/dynload/reloc_table.h 2008-08-18 10:38:35.000000000 +0300
3856 @@ -0,0 +1,102 @@
3858 + * linux/drivers/dsp/bridge/dynload/reloc_table.h
3860 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3862 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
3864 + * This package is free software; you can redistribute it and/or modify
3865 + * it under the terms of the GNU General Public License version 2 as
3866 + * published by the Free Software Foundation.
3868 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3869 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3870 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3871 + */
3875 +#ifndef __RELOC_TABLE_H__
3876 +#define __RELOC_TABLE_H__
3878 + * Table of relocation operator properties
3879 + */
3880 +#include <linux/types.h>
3882 +/* How does this relocation operation access the program image? */
3883 +#define ROP_N 0 /* does not access image */
3884 +#define ROP_R 1 /* read from image */
3885 +#define ROP_W 2 /* write to image */
3886 +#define ROP_RW 3 /* read from and write to image */
3888 +/* For program image access, what are the overflow rules for the bit field? */
3889 +/* Beware! Procedure repack depends on this encoding */
3890 +#define ROP_ANY 0 /* no overflow ever, just truncate the value */
3891 +#define ROP_SGN 1 /* signed field */
3892 +#define ROP_UNS 2 /* unsigned field */
3893 +#define ROP_MAX 3 /* allow maximum range of either signed or unsigned */
3895 +/* How does the relocation operation use the symbol reference */
3896 +#define ROP_IGN 0 /* no symbol is referenced */
3897 +#define ROP_LIT 0 /* use rp->r_uval literal field */
3898 +#define ROP_SYM 1 /* symbol value is used in relocation */
3899 +#define ROP_SYMD 2 /* delta value vs last link is used */
3901 +/* How does the reloc op use the stack? */
3902 +#define RSTK_N 0 /* Does not use */
3903 +#define RSTK_POP 1 /* Does a POP */
3904 +#define RSTK_UOP 2 /* Unary op, stack position unaffected */
3905 +#define RSTK_PSH 3 /* Does a push */
3908 + * Computational actions performed by the dynamic loader
3909 + */
3910 +enum Dload_Actions {
3911 + RACT_VAL, /* don't alter the current val (from stack or mem fetch) */
3912 + RACT_ASGN, /* set value to reference amount (from symbol reference) */
3913 + RACT_ADD, /* add reference to value */
3914 + RACT_PCR, /* add reference minus PC delta to value */
3915 + RACT_ADDISP, /* add reference plus r_disp */
3916 + RACT_ASGPC, /* set value to section address plus reference */
3918 + RACT_PLUS, /* stack + */
3919 + RACT_SUB, /* stack - */
3920 + RACT_NEG, /* stack unary - */
3922 + RACT_MPY, /* stack * */
3923 + RACT_DIV, /* stack / */
3924 + RACT_MOD, /* stack % */
3926 + RACT_SR, /* stack unsigned >> */
3927 + RACT_ASR, /* stack signed >> */
3928 + RACT_SL, /* stack << */
3929 + RACT_AND, /* stack & */
3930 + RACT_OR, /* stack | */
3931 + RACT_XOR, /* stack ^ */
3932 + RACT_NOT, /* stack ~ */
3933 + RACT_C6SECT, /* for C60 R_SECT op */
3934 + RACT_C6BASE, /* for C60 R_BASE op */
3935 + RACT_C6DSPL, /* for C60 scaled 15-bit displacement */
3936 + RACT_PCR23T /* for ARM Thumb long branch */
3940 + * macros used to extract values
3941 + */
3942 +#define RFV_POSN(aaa) ((aaa) & 0xF)
3943 +#define RFV_WIDTH(aaa) (((aaa) >> 4) & 0x3F)
3944 +#define RFV_ACTION(aaa) ((aaa) >> 10)
3946 +#define RFV_SIGN(iii) (((iii) >> 2) & 0x3)
3947 +#define RFV_SYM(iii) (((iii) >> 4) & 0x3)
3948 +#define RFV_STK(iii) (((iii) >> 6) & 0x3)
3949 +#define RFV_ACCS(iii) ((iii) & 0x3)
3951 +#if (TMS32060)
3952 +#define RFV_SCALE(iii) ((iii) >> 11)
3953 +#define RFV_BIGOFF(iii) (((iii) >> 8) & 0x7)
3954 +#else
3955 +#define RFV_BIGOFF(iii) ((iii) >> 8)
3956 +#endif
3958 +#endif /* __RELOC_TABLE_H__ */
3959 Index: lk/drivers/dsp/bridge/dynload/reloc_table_c6000.c
3960 ===================================================================
3961 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3962 +++ lk/drivers/dsp/bridge/dynload/reloc_table_c6000.c 2008-08-18 10:38:35.000000000 +0300
3963 @@ -0,0 +1,258 @@
3965 + * linux/drivers/dsp/bridge/dynload/reloc_table_c6000.c
3967 + * DSP-BIOS Bridge driver support functions for TI OMAP processors.
3969 + * Copyright (C) 2005-2006 Texas Instruments, Inc.
3971 + * This package is free software; you can redistribute it and/or modify
3972 + * it under the terms of the GNU General Public License version 2 as
3973 + * published by the Free Software Foundation.
3975 + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
3976 + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
3977 + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
3978 + */
3981 +/* Tables generated for c6000 */
3983 +#define HASH_FUNC(zz) (((((zz) + 1) * UINT32_C(1845)) >> 11) & 63)
3984 +#define HASH_L(zz) ((zz) >> 8)
3985 +#define HASH_I(zz) ((zz) & 0xFF)
3987 +static const u16 rop_map1[] = {
3988 + 0,
3989 + 1,
3990 + 2,
3991 + 20,
3992 + 4,
3993 + 5,
3994 + 6,
3995 + 15,
3996 + 80,
3997 + 81,
3998 + 82,
3999 + 83,
4000 + 84,
4001 + 85,
4002 + 86,
4003 + 87,
4004 + 17,
4005 + 18,
4006 + 19,
4007 + 21,
4008 + 16,
4009 + 16394,
4010 + 16404,
4011 + 65535,
4012 + 65535,
4013 + 65535,
4014 + 65535,
4015 + 65535,
4016 + 65535,
4017 + 32,
4018 + 65535,
4019 + 65535,
4020 + 65535,
4021 + 65535,
4022 + 65535,
4023 + 65535,
4024 + 40,
4025 + 112,
4026 + 113,
4027 + 65535,
4028 + 16384,
4029 + 16385,
4030 + 16386,
4031 + 16387,
4032 + 16388,
4033 + 16389,
4034 + 16390,
4035 + 16391,
4036 + 16392,
4037 + 16393,
4038 + 16395,
4039 + 16396,
4040 + 16397,
4041 + 16398,
4042 + 16399,
4043 + 16400,
4044 + 16401,
4045 + 16402,
4046 + 16403,
4047 + 16405,
4048 + 16406,
4049 + 65535,
4050 + 65535,
4051 + 65535
4054 +static const s16 rop_map2[] = {
4055 + -256,
4056 + -255,
4057 + -254,
4058 + -245,
4059 + -253,
4060 + -252,
4061 + -251,
4062 + -250,
4063 + -241,
4064 + -240,
4065 + -239,
4066 + -238,
4067 + -237,
4068 + -236,
4069 + 1813,
4070 + 5142,
4071 + -248,
4072 + -247,
4073 + 778,
4074 + -244,
4075 + -249,
4076 + -221,
4077 + -211,
4078 + -1,
4079 + -1,
4080 + -1,
4081 + -1,
4082 + -1,
4083 + -1,
4084 + -243,
4085 + -1,
4086 + -1,
4087 + -1,
4088 + -1,
4089 + -1,
4090 + -1,
4091 + -242,
4092 + -233,
4093 + -232,
4094 + -1,
4095 + -231,
4096 + -230,
4097 + -229,
4098 + -228,
4099 + -227,
4100 + -226,
4101 + -225,
4102 + -224,
4103 + -223,
4104 + 5410,
4105 + -220,
4106 + -219,
4107 + -218,
4108 + -217,
4109 + -216,
4110 + -215,
4111 + -214,
4112 + -213,
4113 + 5676,
4114 + -210,
4115 + -209,
4116 + -1,
4117 + -1,
4118 + -1
4121 +static const u16 rop_action[] = {
4122 + 2560,
4123 + 2304,
4124 + 2304,
4125 + 2432,
4126 + 2432,
4127 + 2560,
4128 + 2176,
4129 + 2304,
4130 + 2560,
4131 + 3200,
4132 + 3328,
4133 + 3584,
4134 + 3456,
4135 + 2304,
4136 + 4208,
4137 + 20788,
4138 + 21812,
4139 + 3415,
4140 + 3245,
4141 + 2311,
4142 + 4359,
4143 + 19764,
4144 + 2311,
4145 + 3191,
4146 + 3280,
4147 + 6656,
4148 + 7680,
4149 + 8704,
4150 + 9728,
4151 + 10752,
4152 + 11776,
4153 + 12800,
4154 + 13824,
4155 + 14848,
4156 + 15872,
4157 + 16896,
4158 + 17920,
4159 + 18944,
4160 + 0,
4161 + 0,
4162 + 0,
4163 + 0,
4164 + 1536,
4165 + 1536,
4166 + 1536,
4167 + 5632,
4168 + 512,
4172 +static const u16 rop_info[] = {
4173 + 0,
4174 + 35,
4175 + 35,
4176 + 35,
4177 + 35,
4178 + 35,
4179 + 35,
4180 + 35,
4181 + 35,
4182 + 39,
4183 + 39,
4184 + 39,
4185 + 39,
4186 + 35,
4187 + 34,
4188 + 283,
4189 + 299,
4190 + 4135,
4191 + 4391,
4192 + 291,
4193 + 33059,
4194 + 283,
4195 + 295,
4196 + 4647,
4197 + 4135,
4198 + 64,
4199 + 64,
4200 + 128,
4201 + 64,
4202 + 64,
4203 + 64,
4204 + 64,
4205 + 64,
4206 + 64,
4207 + 64,
4208 + 64,
4209 + 64,
4210 + 128,
4211 + 201,
4212 + 197,
4213 + 74,
4214 + 70,
4215 + 208,
4216 + 196,
4217 + 200,
4218 + 192,
4219 + 192,
4220 + 66