linux/drivers/staging/tidspbridge/dynload/dload_internal.h
<<
>>
Prefs
   1/*
   2 * dload_internal.h
   3 *
   4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
   5 *
   6 * Copyright (C) 2005-2006 Texas Instruments, Inc.
   7 *
   8 * This package is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 *
  12 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  13 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  14 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  15 */
  16
  17#ifndef _DLOAD_INTERNAL_
  18#define _DLOAD_INTERNAL_
  19
  20#include <linux/types.h>
  21
  22/*
  23 * Internal state definitions for the dynamic loader
  24 */
  25
  26/* type used for relocation intermediate results */
  27typedef s32 rvalue;
  28
  29/* unsigned version of same; must have at least as many bits */
  30typedef u32 urvalue;
  31
  32/*
  33 * Dynamic loader configuration constants
  34 */
  35/* error issued if input has more sections than this limit */
  36#define REASONABLE_SECTION_LIMIT 100
  37
  38/* (Addressable unit) value used to clear BSS section */
  39#define DLOAD_FILL_BSS 0
  40
  41/*
  42 * Reorder maps explained (?)
  43 *
  44 * The doff file format defines a 32-bit pattern used to determine the
  45 * byte order of an image being read.  That value is
  46 * BYTE_RESHUFFLE_VALUE == 0x00010203
  47 * For purposes of the reorder routine, we would rather have the all-is-OK
  48 * for 32-bits pattern be 0x03020100.  This first macro makes the
  49 * translation from doff file header value to MAP value: */
  50#define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303)
  51/* This translation is made in dload_headers.  Thereafter, the all-is-OK
  52 * value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE).
  53 * But sadly, not all bits of the doff file are 32-bit integers.
  54 * The notable exceptions are strings and image bits.
  55 * Strings obey host byte order: */
  56#if defined(_BIG_ENDIAN)
  57#define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
  58#else
  59#define HOST_BYTE_ORDER(cookedmap) (cookedmap)
  60#endif
  61/* Target bits consist of target AUs (could be bytes, or 16-bits,
  62 * or 32-bits) stored as an array in host order.  A target order
  63 * map is defined by: */
  64#if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16
  65#define TARGET_ORDER(cookedmap) (cookedmap)
  66#elif TARGET_AU_BITS > 8
  67#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202)
  68#else
  69#define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
  70#endif
  71
  72/* forward declaration for handle returned by dynamic loader */
  73struct my_handle;
  74
  75/*
  76 * a list of module handles, which mirrors the debug list on the target
  77 */
  78struct dbg_mirror_root {
  79        /* must be same as dbg_mirror_list; __DLModules address on target */
  80        u32 dbthis;
  81        struct my_handle *next; /* must be same as dbg_mirror_list */
  82        u16 changes;            /* change counter */
  83        u16 refcount;           /* number of modules referencing this root */
  84};
  85
  86struct dbg_mirror_list {
  87        u32 dbthis;
  88        struct my_handle *next, *prev;
  89        struct dbg_mirror_root *root;
  90        u16 dbsiz;
  91        u32 context;    /* Save context for .dllview memory allocation */
  92};
  93
  94#define VARIABLE_SIZE 1
  95/*
  96 * the structure we actually return as an opaque module handle
  97 */
  98struct my_handle {
  99        struct dbg_mirror_list dm;      /* !!! must be first !!! */
 100        /* sections following << 1, LSB is set for big-endian target */
 101        u16 secn_count;
 102        struct ldr_section_info secns[VARIABLE_SIZE];
 103};
 104#define MY_HANDLE_SIZE (sizeof(struct my_handle) -\
 105                        sizeof(struct ldr_section_info))
 106/* real size of my_handle */
 107
 108/*
 109 * reduced symbol structure used for symbols during relocation
 110 */
 111struct local_symbol {
 112        s32 value;              /* Relocated symbol value */
 113        s32 delta;              /* Original value in input file */
 114        s16 secnn;              /* section number */
 115        s16 sclass;             /* symbol class */
 116};
 117
 118/*
 119 * Trampoline data structures
 120 */
 121#define TRAMP_NO_GEN_AVAIL              65535
 122#define TRAMP_SYM_PREFIX                "__$dbTR__"
 123#define TRAMP_SECT_NAME                 ".dbTR"
 124/* MUST MATCH THE LENGTH ABOVE!! */
 125#define TRAMP_SYM_PREFIX_LEN            9
 126/* Includes NULL termination */
 127#define TRAMP_SYM_HEX_ASCII_LEN         9
 128
 129#define GET_CONTAINER(ptr, type, field) ((type *)((unsigned long)ptr -\
 130                                (unsigned long)(&((type *)0)->field)))
 131#ifndef FIELD_OFFSET
 132#define FIELD_OFFSET(type, field)       ((unsigned long)(&((type *)0)->field))
 133#endif
 134
 135/*
 136    The trampoline code for the target is located in a table called
 137    "tramp_gen_info" with is indexed by looking up the index in the table
 138    "tramp_map".  The tramp_map index is acquired using the target
 139    HASH_FUNC on the relocation type that caused the trampoline.  Each
 140    trampoline code table entry MUST follow this format:
 141
 142    |----------------------------------------------|
 143    |  tramp_gen_code_hdr                          |
 144    |----------------------------------------------|
 145    |  Trampoline image code                       |
 146    |  (the raw instruction code for the target)   |
 147    |----------------------------------------------|
 148    |  Relocation entries for the image code       |
 149    |----------------------------------------------|
 150
 151    This is very similar to how image data is laid out in the DOFF file
 152    itself.
 153 */
 154struct tramp_gen_code_hdr {
 155        u32 tramp_code_size;    /*  in BYTES */
 156        u32 num_relos;
 157        u32 relo_offset;        /*  in BYTES */
 158};
 159
 160struct tramp_img_pkt {
 161        struct tramp_img_pkt *next;     /*  MUST BE FIRST */
 162        u32 base;
 163        struct tramp_gen_code_hdr hdr;
 164        u8 payload[VARIABLE_SIZE];
 165};
 166
 167struct tramp_img_dup_relo {
 168        struct tramp_img_dup_relo *next;
 169        struct reloc_record_t relo;
 170};
 171
 172struct tramp_img_dup_pkt {
 173        struct tramp_img_dup_pkt *next; /*  MUST BE FIRST */
 174        s16 secnn;
 175        u32 offset;
 176        struct image_packet_t img_pkt;
 177        struct tramp_img_dup_relo *relo_chain;
 178
 179        /*  PAYLOAD OF IMG PKT FOLLOWS */
 180};
 181
 182struct tramp_sym {
 183        struct tramp_sym *next; /*  MUST BE FIRST */
 184        u32 index;
 185        u32 str_index;
 186        struct local_symbol sym_info;
 187};
 188
 189struct tramp_string {
 190        struct tramp_string *next;      /*  MUST BE FIRST */
 191        u32 index;
 192        char str[VARIABLE_SIZE];        /*  NULL terminated */
 193};
 194
 195struct tramp_info {
 196        u32 tramp_sect_next_addr;
 197        struct ldr_section_info sect_info;
 198
 199        struct tramp_sym *symbol_head;
 200        struct tramp_sym *symbol_tail;
 201        u32 tramp_sym_next_index;
 202        struct local_symbol *final_sym_table;
 203
 204        struct tramp_string *string_head;
 205        struct tramp_string *string_tail;
 206        u32 tramp_string_next_index;
 207        u32 tramp_string_size;
 208        char *final_string_table;
 209
 210        struct tramp_img_pkt *tramp_pkts;
 211        struct tramp_img_dup_pkt *dup_pkts;
 212};
 213
 214/*
 215 * States of the .cinit state machine
 216 */
 217enum cinit_mode {
 218        CI_COUNT = 0,           /* expecting a count */
 219        CI_ADDRESS,             /* expecting an address */
 220#if CINIT_ALIGN < CINIT_ADDRESS /* handle case of partial address field */
 221        CI_PARTADDRESS,         /* have only part of the address */
 222#endif
 223        CI_COPY,                /* in the middle of copying data */
 224        CI_DONE                 /* end of .cinit table */
 225};
 226
 227/*
 228 * The internal state of the dynamic loader, which is passed around as
 229 * an object
 230 */
 231struct dload_state {
 232        struct dynamic_loader_stream *strm;     /* The module input stream */
 233        struct dynamic_loader_sym *mysym;       /* Symbols for this session */
 234        /* target memory allocator */
 235        struct dynamic_loader_allocate *myalloc;
 236        struct dynamic_loader_initialize *myio; /* target memory initializer */
 237        unsigned myoptions;     /* Options parameter dynamic_load_module */
 238
 239        char *str_head;         /* Pointer to string table */
 240#if BITS_PER_AU > BITS_PER_BYTE
 241        char *str_temp;         /* Pointer to temporary buffer for strings */
 242        /* big enough to hold longest string */
 243        unsigned temp_len;      /* length of last temporary string */
 244        char *xstrings;         /* Pointer to buffer for expanded */
 245        /* strings for sec names */
 246#endif
 247        /* Total size of strings for DLLView section names */
 248        unsigned debug_string_size;
 249        /* Pointer to parallel section info for allocated sections only */
 250        struct doff_scnhdr_t *sect_hdrs;        /* Pointer to section table */
 251        struct ldr_section_info *ldr_sections;
 252#if TMS32060
 253        /* The address of the start of the .bss section */
 254        ldr_addr bss_run_base;
 255#endif
 256        struct local_symbol *local_symtab;      /* Relocation symbol table */
 257
 258        /* pointer to DL section info for the section being relocated */
 259        struct ldr_section_info *image_secn;
 260        /* change in run address for current section during relocation */
 261        ldr_addr delta_runaddr;
 262        ldr_addr image_offset;  /* offset of current packet in section */
 263        enum cinit_mode cinit_state;    /* current state of cload_cinit() */
 264        int cinit_count;        /* the current count */
 265        ldr_addr cinit_addr;    /* the current address */
 266        s16 cinit_page;         /* the current page */
 267        /* Handle to be returned by dynamic_load_module */
 268        struct my_handle *myhandle;
 269        unsigned dload_errcount;        /* Total # of errors reported so far */
 270        /* Number of target sections that require allocation and relocation */
 271        unsigned allocated_secn_count;
 272#ifndef TARGET_ENDIANNESS
 273        int big_e_target;       /* Target data in big-endian format */
 274#endif
 275        /* map for reordering bytes, 0 if not needed */
 276        u32 reorder_map;
 277        struct doff_filehdr_t dfile_hdr;        /* DOFF file header structure */
 278        struct doff_verify_rec_t verify;        /* Verify record */
 279
 280        struct tramp_info tramp;        /* Trampoline data, if needed */
 281
 282        int relstkidx;          /* index into relocation value stack */
 283        /* relocation value stack used in relexp.c */
 284        rvalue relstk[STATIC_EXPR_STK_SIZE];
 285
 286};
 287
 288#ifdef TARGET_ENDIANNESS
 289#define TARGET_BIG_ENDIAN TARGET_ENDIANNESS
 290#else
 291#define TARGET_BIG_ENDIAN (dlthis->big_e_target)
 292#endif
 293
 294/*
 295 * Exports from cload.c to rest of the world
 296 */
 297extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...);
 298extern void dload_syms_error(struct dynamic_loader_sym *syms,
 299                             const char *errtxt, ...);
 300extern void dload_headers(struct dload_state *dlthis);
 301extern void dload_strings(struct dload_state *dlthis, bool sec_names_only);
 302extern void dload_sections(struct dload_state *dlthis);
 303extern void dload_reorder(void *data, int dsiz, u32 map);
 304extern u32 dload_checksum(void *data, unsigned siz);
 305
 306#if HOST_ENDIANNESS
 307extern uint32_t dload_reverse_checksum(void *data, unsigned siz);
 308#if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
 309extern uint32_t dload_reverse_checksum16(void *data, unsigned siz);
 310#endif
 311#endif
 312
 313/*
 314 * exported by reloc.c
 315 */
 316extern void dload_relocate(struct dload_state *dlthis, tgt_au_t * data,
 317                           struct reloc_record_t *rp, bool * tramps_generated,
 318                           bool second_pass);
 319
 320extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data,
 321                           int fieldsz, int offset, unsigned sgn);
 322
 323extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t * data,
 324                        int fieldsz, int offset, unsigned sgn);
 325
 326/*
 327 * exported by tramp.c
 328 */
 329extern bool dload_tramp_avail(struct dload_state *dlthis,
 330                              struct reloc_record_t *rp);
 331
 332int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
 333                         u32 image_offset, struct image_packet_t *ipacket,
 334                         struct reloc_record_t *rp);
 335
 336extern int dload_tramp_pkt_udpate(struct dload_state *dlthis,
 337                                  s16 secnn, u32 image_offset,
 338                                  struct image_packet_t *ipacket);
 339
 340extern int dload_tramp_finalize(struct dload_state *dlthis);
 341
 342extern void dload_tramp_cleanup(struct dload_state *dlthis);
 343
 344#endif /* _DLOAD_INTERNAL_ */
 345