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 */ 27 typedef s32 rvalue; 28 29 /* unsigned version of same; must have at least as many bits */ 30 typedef 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 */ 73 struct my_handle; 74 75 /* 76 * a list of module handles, which mirrors the debug list on the target 77 */ 78 struct 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 86 struct 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 */ 98 struct 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 */ 111 struct 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 */ 154 struct tramp_gen_code_hdr { 155 u32 tramp_code_size; /* in BYTES */ 156 u32 num_relos; 157 u32 relo_offset; /* in BYTES */ 158 }; 159 160 struct 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 167 struct tramp_img_dup_relo { 168 struct tramp_img_dup_relo *next; 169 struct reloc_record_t relo; 170 }; 171 172 struct 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 182 struct 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 189 struct tramp_string { 190 struct tramp_string *next; /* MUST BE FIRST */ 191 u32 index; 192 char str[VARIABLE_SIZE]; /* NULL terminated */ 193 }; 194 195 struct 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 */ 217 enum 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 */ 231 struct 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 */ 297 extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...); 298 extern void dload_syms_error(struct dynamic_loader_sym *syms, 299 const char *errtxt, ...); 300 extern void dload_headers(struct dload_state *dlthis); 301 extern void dload_strings(struct dload_state *dlthis, bool sec_names_only); 302 extern void dload_sections(struct dload_state *dlthis); 303 extern void dload_reorder(void *data, int dsiz, u32 map); 304 extern u32 dload_checksum(void *data, unsigned siz); 305 306 #if HOST_ENDIANNESS 307 extern uint32_t dload_reverse_checksum(void *data, unsigned siz); 308 #if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32) 309 extern uint32_t dload_reverse_checksum16(void *data, unsigned siz); 310 #endif 311 #endif 312 313 /* 314 * exported by reloc.c 315 */ 316 extern 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 320 extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data, 321 int fieldsz, int offset, unsigned sgn); 322 323 extern 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 */ 329 extern bool dload_tramp_avail(struct dload_state *dlthis, 330 struct reloc_record_t *rp); 331 332 int 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 336 extern int dload_tramp_pkt_udpate(struct dload_state *dlthis, 337 s16 secnn, u32 image_offset, 338 struct image_packet_t *ipacket); 339 340 extern int dload_tramp_finalize(struct dload_state *dlthis); 341 342 extern void dload_tramp_cleanup(struct dload_state *dlthis); 343 344 #endif /* _DLOAD_INTERNAL_ */ 345