4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * Copyright (C) 2005-2006 Texas Instruments, Inc.
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.
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.
17 #ifndef _DLOAD_INTERNAL_
18 #define _DLOAD_INTERNAL_
20 #include <linux/types.h>
23 * Internal state definitions for the dynamic loader
29 /* type used for relocation intermediate results */
32 /* unsigned version of same; must have at least as many bits */
36 * Dynamic loader configuration constants
38 /* error issued if input has more sections than this limit */
39 #define REASONABLE_SECTION_LIMIT 100
41 /* (Addressable unit) value used to clear BSS section */
42 #define DLOAD_FILL_BSS 0
45 * Reorder maps explained (?)
47 * The doff file format defines a 32-bit pattern used to determine the
48 * byte order of an image being read. That value is
49 * BYTE_RESHUFFLE_VALUE == 0x00010203
50 * For purposes of the reorder routine, we would rather have the all-is-OK
51 * for 32-bits pattern be 0x03020100. This first macro makes the
52 * translation from doff file header value to MAP value: */
53 #define REORDER_MAP(rawmap) ((rawmap) ^ 0x3030303)
54 /* This translation is made in dload_headers. Thereafter, the all-is-OK
55 * value for the maps stored in dlthis is REORDER_MAP(BYTE_RESHUFFLE_VALUE).
56 * But sadly, not all bits of the doff file are 32-bit integers.
57 * The notable exceptions are strings and image bits.
58 * Strings obey host byte order: */
59 #if defined(_BIG_ENDIAN)
60 #define HOST_BYTE_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
62 #define HOST_BYTE_ORDER(cookedmap) (cookedmap)
64 /* Target bits consist of target AUs (could be bytes, or 16-bits,
65 * or 32-bits) stored as an array in host order. A target order
66 * map is defined by: */
67 #if !defined(_BIG_ENDIAN) || TARGET_AU_BITS > 16
68 #define TARGET_ORDER(cookedmap) (cookedmap)
69 #elif TARGET_AU_BITS > 8
70 #define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x2020202)
72 #define TARGET_ORDER(cookedmap) ((cookedmap) ^ 0x3030303)
75 /* forward declaration for handle returned by dynamic loader */
79 * a list of module handles, which mirrors the debug list on the target
81 struct dbg_mirror_root {
82 /* must be same as dbg_mirror_list; __DLModules address on target */
84 struct my_handle *hnext; /* must be same as dbg_mirror_list */
85 u16 changes; /* change counter */
86 u16 refcount; /* number of modules referencing this root */
89 struct dbg_mirror_list {
91 struct my_handle *hnext, *hprev;
92 struct dbg_mirror_root *hroot;
94 u32 context; /* Save context for .dllview memory allocation */
97 #define VARIABLE_SIZE 1
99 * the structure we actually return as an opaque module handle
102 struct dbg_mirror_list dm; /* !!! must be first !!! */
103 /* sections following << 1, LSB is set for big-endian target */
105 struct ldr_section_info secns[VARIABLE_SIZE];
107 #define MY_HANDLE_SIZE (sizeof(struct my_handle) -\
108 sizeof(struct ldr_section_info))
109 /* real size of my_handle */
112 * reduced symbol structure used for symbols during relocation
114 struct local_symbol {
115 s32 value; /* Relocated symbol value */
116 s32 delta; /* Original value in input file */
117 s16 secnn; /* section number */
118 s16 sclass; /* symbol class */
122 * Trampoline data structures
124 #define TRAMP_NO_GEN_AVAIL 65535
125 #define TRAMP_SYM_PREFIX "__$dbTR__"
126 #define TRAMP_SECT_NAME ".dbTR"
127 /* MUST MATCH THE LENGTH ABOVE!! */
128 #define TRAMP_SYM_PREFIX_LEN 9
129 /* Includes NULL termination */
130 #define TRAMP_SYM_HEX_ASCII_LEN 9
132 #define GET_CONTAINER(ptr, type, field) ((type *)((unsigned long)ptr -\
133 (unsigned long)(&((type *)0)->field)))
135 #define FIELD_OFFSET(type, field) ((unsigned long)(&((type *)0)->field))
139 The trampoline code for the target is located in a table called
140 "tramp_gen_info" with is indexed by looking up the index in the table
141 "tramp_map". The tramp_map index is acquired using the target
142 HASH_FUNC on the relocation type that caused the trampoline. Each
143 trampoline code table entry MUST follow this format:
145 |----------------------------------------------|
146 | tramp_gen_code_hdr |
147 |----------------------------------------------|
148 | Trampoline image code |
149 | (the raw instruction code for the target) |
150 |----------------------------------------------|
151 | Relocation entries for the image code |
152 |----------------------------------------------|
154 This is very similar to how image data is laid out in the DOFF file
157 struct tramp_gen_code_hdr {
158 u32 tramp_code_size; /* in BYTES */
160 u32 relo_offset; /* in BYTES */
163 struct tramp_img_pkt {
164 struct tramp_img_pkt *next; /* MUST BE FIRST */
166 struct tramp_gen_code_hdr hdr;
167 u8 payload[VARIABLE_SIZE];
170 struct tramp_img_dup_relo {
171 struct tramp_img_dup_relo *next;
172 struct reloc_record_t relo;
175 struct tramp_img_dup_pkt {
176 struct tramp_img_dup_pkt *next; /* MUST BE FIRST */
179 struct image_packet_t img_pkt;
180 struct tramp_img_dup_relo *relo_chain;
182 /* PAYLOAD OF IMG PKT FOLLOWS */
186 struct tramp_sym *next; /* MUST BE FIRST */
189 struct local_symbol sym_info;
192 struct tramp_string {
193 struct tramp_string *next; /* MUST BE FIRST */
195 char str[VARIABLE_SIZE]; /* NULL terminated */
199 u32 tramp_sect_next_addr;
200 struct ldr_section_info sect_info;
202 struct tramp_sym *symbol_head;
203 struct tramp_sym *symbol_tail;
204 u32 tramp_sym_next_index;
205 struct local_symbol *final_sym_table;
207 struct tramp_string *string_head;
208 struct tramp_string *string_tail;
209 u32 tramp_string_next_index;
210 u32 tramp_string_size;
211 char *final_string_table;
213 struct tramp_img_pkt *tramp_pkts;
214 struct tramp_img_dup_pkt *dup_pkts;
218 * States of the .cinit state machine
221 CI_COUNT = 0, /* expecting a count */
222 CI_ADDRESS, /* expecting an address */
223 #if CINIT_ALIGN < CINIT_ADDRESS /* handle case of partial address field */
224 CI_PARTADDRESS, /* have only part of the address */
226 CI_COPY, /* in the middle of copying data */
227 CI_DONE /* end of .cinit table */
231 * The internal state of the dynamic loader, which is passed around as
235 struct dynamic_loader_stream *strm; /* The module input stream */
236 struct dynamic_loader_sym *mysym; /* Symbols for this session */
237 /* target memory allocator */
238 struct dynamic_loader_allocate *myalloc;
239 struct dynamic_loader_initialize *myio; /* target memory initializer */
240 unsigned myoptions; /* Options parameter dynamic_load_module */
242 char *str_head; /* Pointer to string table */
243 #if BITS_PER_AU > BITS_PER_BYTE
244 char *str_temp; /* Pointer to temporary buffer for strings */
245 /* big enough to hold longest string */
246 unsigned temp_len; /* length of last temporary string */
247 char *xstrings; /* Pointer to buffer for expanded */
248 /* strings for sec names */
250 /* Total size of strings for DLLView section names */
251 unsigned debug_string_size;
252 /* Pointer to parallel section info for allocated sections only */
253 struct doff_scnhdr_t *sect_hdrs; /* Pointer to section table */
254 struct ldr_section_info *ldr_sections;
256 /* The address of the start of the .bss section */
257 ldr_addr bss_run_base;
259 struct local_symbol *local_symtab; /* Relocation symbol table */
261 /* pointer to DL section info for the section being relocated */
262 struct ldr_section_info *image_secn;
263 /* change in run address for current section during relocation */
264 ldr_addr delta_runaddr;
265 ldr_addr image_offset; /* offset of current packet in section */
266 enum cinit_mode cinit_state; /* current state of cload_cinit() */
267 int cinit_count; /* the current count */
268 ldr_addr cinit_addr; /* the current address */
269 s16 cinit_page; /* the current page */
270 /* Handle to be returned by dynamic_load_module */
271 struct my_handle *myhandle;
272 unsigned dload_errcount; /* Total # of errors reported so far */
273 /* Number of target sections that require allocation and relocation */
274 unsigned allocated_secn_count;
275 #ifndef TARGET_ENDIANNESS
276 int big_e_target; /* Target data in big-endian format */
278 /* map for reordering bytes, 0 if not needed */
280 struct doff_filehdr_t dfile_hdr; /* DOFF file header structure */
281 struct doff_verify_rec_t verify; /* Verify record */
283 struct tramp_info tramp; /* Trampoline data, if needed */
285 int relstkidx; /* index into relocation value stack */
286 /* relocation value stack used in relexp.c */
287 rvalue relstk[STATIC_EXPR_STK_SIZE];
291 #ifdef TARGET_ENDIANNESS
292 #define TARGET_BIG_ENDIAN TARGET_ENDIANNESS
294 #define TARGET_BIG_ENDIAN (dlthis->big_e_target)
298 * Exports from cload.c to rest of the world
300 extern void dload_error(struct dload_state *dlthis, const char *errtxt, ...);
301 extern void dload_syms_error(struct dynamic_loader_sym *syms,
302 const char *errtxt, ...);
303 extern void dload_headers(struct dload_state *dlthis);
304 extern void dload_strings(struct dload_state *dlthis, bool sec_names_only);
305 extern void dload_sections(struct dload_state *dlthis);
306 extern void dload_reorder(void *data, int dsiz, u32 map);
307 extern u32 dload_checksum(void *data, unsigned siz);
310 extern uint32_t dload_reverse_checksum(void *data, unsigned siz);
311 #if (TARGET_AU_BITS > 8) && (TARGET_AU_BITS < 32)
312 extern uint32_t dload_reverse_checksum16(void *data, unsigned siz);
316 #define IS_DATA_SCN(zzz) (DLOAD_SECTION_TYPE((zzz)->type) != DLOAD_TEXT)
317 #define IS_DATA_SCN_NUM(zzz) \
318 (DLOAD_SECT_TYPE(&dlthis->sect_hdrs[(zzz)-1]) != DLOAD_TEXT)
321 * exported by reloc.c
323 extern void dload_relocate(struct dload_state *dlthis, tgt_au_t * data,
324 struct reloc_record_t *rp, bool * tramps_generated,
327 extern rvalue dload_unpack(struct dload_state *dlthis, tgt_au_t * data,
328 int fieldsz, int offset, unsigned sgn);
330 extern int dload_repack(struct dload_state *dlthis, rvalue val, tgt_au_t * data,
331 int fieldsz, int offset, unsigned sgn);
334 * exported by tramp.c
336 extern bool dload_tramp_avail(struct dload_state *dlthis,
337 struct reloc_record_t *rp);
339 int dload_tramp_generate(struct dload_state *dlthis, s16 secnn,
340 u32 image_offset, struct image_packet_t *ipacket,
341 struct reloc_record_t *rp);
343 extern int dload_tramp_pkt_udpate(struct dload_state *dlthis,
344 s16 secnn, u32 image_offset,
345 struct image_packet_t *ipacket);
347 extern int dload_tramp_finalize(struct dload_state *dlthis);
349 extern void dload_tramp_cleanup(struct dload_state *dlthis);
351 #endif /* _DLOAD_INTERNAL_ */