1 static char _[] = "@(#)yank.c 5.20 93/07/30 16:39:05, Srini, AMD. ";
2 /******************************************************************************
3 * Copyright 1991 Advanced Micro Devices, Inc.
5 * This software is the property of Advanced Micro Devices, Inc (AMD) which
6 * specifically grants the user the right to modify, use and distribute this
7 * software provided this notice is not removed or altered. All other rights
10 * AMD MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH REGARD TO THIS
11 * SOFTWARE. IN NO EVENT SHALL AMD BE LIABLE FOR INCIDENTAL OR CONSEQUENTIAL
12 * DAMAGES IN CONNECTION WITH OR ARISING FROM THE FURNISHING, PERFORMANCE, OR
13 * USE OF THIS SOFTWARE.
15 * So that all may benefit from your experience, please report any problems
16 * or suggestions about this software to the 29K Technical Support Center at
17 * 800-29-29-AMD (800-292-9263) in the USA, or 0800-89-1131 in the UK, or
18 * 0031-11-1129 in Japan, toll free. The direct dial number is 512-462-4118.
20 * Advanced Micro Devices, Inc.
21 * 29K Support Products
23 * 5900 E. Ben White Blvd.
26 *****************************************************************************
27 * Engineer: Srini Subramanian.
28 *****************************************************************************
29 ** This module is used to "yank" or load a COFF file
30 ** Into target memory.
31 *****************************************************************************
54 #define FILE_BUFFER_SIZE 1024
57 #define FILE_OPEN_FLAG "rb"
59 #define FILE_OPEN_FLAG "r"
62 #define FROM_BEGINNING 0
64 /* Function declarations */
65 INT32 Mini_load_coff PARAMS((char *fname,
70 INT32 Mini_init_info_ptr PARAMS((INIT_INFO *init));
71 INT32 Mini_send_init_info PARAMS((INIT_INFO *init));
72 INT32 Mini_load_file PARAMS((char *fname,
79 void convert32 PARAMS((BYTE *));
80 void convert16 PARAMS((BYTE *));
81 int SetSections PARAMS((char *));
82 void print_ld_msg PARAMS((INT32, int, ADDR32, INT32));
83 void print_ign_msg PARAMS((int, ADDR32, INT32));
84 void print_end_msg PARAMS((INT32, int, ADDR32, INT32));
88 GLOBAL INIT_INFO init_info;
90 static BYTE buffer[FILE_BUFFER_SIZE];
91 extern char CoffFileName[];
92 static INT32 Symbols=0; /* No symbols support yet */
93 static INT32 Sections=STYP_ABS | STYP_TEXT | STYP_DATA | STYP_LIT | STYP_BSS;
94 static INT32 MSpace=I_MEM;
96 static char ArgString[1024];
98 static int InitializeProgram=1;
102 ** This is the function called by the main program to load
103 ** a COFF file. It also modifies the global data structure
104 ** init. The data structure is then sent via an INIT message
105 ** to the target. In addition, the "argv" parameter string
106 ** is sent to the target with WRITE messages.
111 yank_cmd(token, token_count)
120 for (j=1; j < token_count; j++) { /* parse command */
121 switch (token[j][0]) {
123 if (token[j][1] == '\0')
125 if (strcmp(token[j],"-ms")==0) {/*mem stack opt */
126 if (++j >= token_count)
128 if (sscanf(token[j],"%lx",&(init_info.mem_stack_size)) != 1)
130 } else if (strcmp(token[j],"-rs")==0) {/*r stack*/
131 if (++j >= token_count)
133 if (sscanf(token[j],"%lx",&(init_info.reg_stack_size)) != 1)
135 } else if (strcmp(token[j],"-noi")==0) {/*no init */
136 InitializeProgram = 0;
138 } else if (strcmp(token[j],"-i")==0) {/*init*/
139 InitializeProgram = 1;
142 if (SetSections(token[j]) == (int) -1)
148 default: /* filename etc. */
149 if (!SectionsGiven) {
150 Sections = STYP_ABS|STYP_TEXT|STYP_DATA|STYP_LIT|STYP_BSS;
154 InitializeProgram = 1;
157 (void) strcpy (&CoffFileName[0], token[j]);
158 FileArgc = token_count - j;
159 (void) strcpy(ArgString, token[j]);
160 for (i = 1; i < FileArgc; i++) {
161 strcat(ArgString, " ");
162 strcat(ArgString, token[j+i]);
164 j = token_count; /* break out of for loop */
168 if (strcmp(CoffFileName,"") == 0) /* No COFF file given */
171 if (Mini_load_file(&CoffFileName[0], MSpace,
174 QuietMode) != SUCCESS) {
182 Mini_load_file(filename, mspace, fileargc, fileargs, sym, sects, quietmode)
192 if (Mini_init_info_ptr(&init_info) != SUCCESS)
195 if (Mini_load_coff(filename, mspace, sym, sects, quietmode) != SUCCESS)
198 init_info.argstring = fileargs; /* complete argv string */
200 if (InitializeProgram) {
201 if (Mini_send_init_info(&init_info) != SUCCESS)
211 Mini_init_info_ptr(init_ptr)
215 /* Re-initialize INIT message */
216 init_ptr->text_start = 0xffffffff;
217 init_ptr->text_end = 0;
218 init_ptr->data_start = 0xffffffff;
219 init_ptr->data_end = 0;
220 init_ptr->entry_point = 0;
221 if (init_ptr->mem_stack_size == (UINT32) -1)
222 init_ptr->mem_stack_size = MEM_STACK_SIZE;
223 if (init_ptr->reg_stack_size == (UINT32) -1)
224 init_ptr->reg_stack_size = REG_STACK_SIZE;
225 init_ptr->argstring = (char *) 0;
231 Mini_send_init_info(info_ptr)
236 /* Align INIT values to word boundaries */
237 info_ptr->text_start = ALIGN32(info_ptr->text_start);
238 info_ptr->text_end = ALIGN32(info_ptr->text_end);
239 info_ptr->data_start = ALIGN32(info_ptr->data_start);
240 info_ptr->data_end = ALIGN32(info_ptr->data_end);
241 info_ptr->mem_stack_size = ALIGN32(info_ptr->mem_stack_size);
242 info_ptr->reg_stack_size = ALIGN32(info_ptr->reg_stack_size);
244 /* Send INIT message */
246 if ((retval = Mini_init (info_ptr->text_start,
248 info_ptr->data_start,
250 info_ptr->entry_point,
251 info_ptr->mem_stack_size,
252 info_ptr->reg_stack_size,
253 info_ptr->argstring)) != SUCCESS) {
259 } /* Mini_send_init_info */
264 ** This function is used to load a COFF file. Depending on
265 ** the global variable "target_interface", data will be loaded
266 ** by either EB29K shared memory, PCEB shared memory, EB030
267 ** shared memory or serially.
269 ** In addition, the global data structure "init" is updated.
270 ** This data structure maintains the entry point and various
271 ** other target initialization parameters.
275 Mini_load_coff(filename, mspace, sym, Section, quietmode)
282 unsigned short COFF_sections;
287 INT32 temp_byte_count;
290 struct filehdr COFF_header;
291 struct aouthdr COFF_aout_header;
292 struct scnhdr COFF_section_header;
295 fprintf(stderr, "loading %s\n", filename);
296 if (io_config.echo_mode == (INT32) TRUE)
297 fprintf(io_config.echo_file, "loading %s\n", filename);
300 /* Open the COFF input file (if we can) */
301 if ((coff_in = fopen(filename, FILE_OPEN_FLAG)) == NULL) {
302 warning (EMOPEN); return(FAILURE);
305 /* Read in COFF header information */
306 if (fread((char *)&COFF_header, sizeof(struct filehdr), 1, coff_in) != 1) {
307 fclose(coff_in); warning(EMHDR); return (FAILURE);
311 /* Is it an Am29000 COFF File? */
312 if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x7a01) &&
313 (COFF_header.f_magic != 0x17b) && (COFF_header.f_magic != 0x7b01)) {
314 fclose(coff_in); warning (EMMAGIC); return (FAILURE);
317 /* Get number of COFF sections */
318 if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b))
319 convert16((BYTE *) &COFF_header.f_nscns);
320 COFF_sections = (unsigned short) COFF_header.f_nscns;
322 /* Read in COFF a.out header information (if we can) */
323 if (COFF_header.f_opthdr > 0) {
324 if (fread((char *)&COFF_aout_header, sizeof(struct aouthdr),
326 fclose(coff_in); warning (EMAOUT); return (FAILURE);
328 /* Set entry point in INIT message */
329 init_info.entry_point = COFF_aout_header.entry;
330 if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b)) {
331 convert16((BYTE *) &COFF_header.f_opthdr);
332 convert32((BYTE *) &init_info.entry_point);
338 ** Process COFF section headers
341 /* Process all sections */
342 while ((int) COFF_sections--) {
344 fseek (coff_in, (long) (FILHSZ+(int)COFF_header.f_opthdr+
345 SCNHSZ*(COFF_header.f_nscns-COFF_sections-1)),
348 if (fread(&COFF_section_header, 1, SCNHSZ, coff_in) != SCNHSZ) {
349 fclose(coff_in); warning (EMSCNHDR); return (FAILURE);
352 if ((COFF_header.f_magic != 0x17a) && (COFF_header.f_magic != 0x017b)) {
353 convert32((BYTE *) &(COFF_section_header.s_paddr));
354 convert32((BYTE *) &(COFF_section_header.s_scnptr));
355 convert32((BYTE *) &(COFF_section_header.s_size));
356 convert32((BYTE *) &(COFF_section_header.s_flags));
359 address = COFF_section_header.s_paddr;
360 byte_count = COFF_section_header.s_size;
361 flags = COFF_section_header.s_flags;
363 /* Print downloading messages (if necessary) */
364 if ((flags == (INT32) STYP_TEXT) || (flags == (INT32) (STYP_TEXT | STYP_ABS))) {
365 memory_space = I_MEM;
366 init_info.text_start = MIN((ADDR32) address,
367 (ADDR32) init_info.text_start);
368 init_info.text_end = MAX((ADDR32) (address + byte_count),
369 (ADDR32) init_info.text_end);
370 } else if ((flags == (INT32) STYP_DATA) || (flags == (INT32) (STYP_DATA | STYP_ABS)) ||
371 (flags == (INT32) STYP_LIT) || (flags == (INT32) (STYP_LIT | STYP_ABS)) ||
372 (flags == (INT32) STYP_BSS) || (flags == (INT32) (STYP_BSS | STYP_ABS))) {
373 memory_space = D_MEM;
374 init_info.data_start = MIN((ADDR32) address,
375 (ADDR32) init_info.data_start);
376 init_info.data_end = MAX((ADDR32) (address + byte_count),
377 (ADDR32) init_info.data_end);
379 print_ign_msg(quietmode, address, byte_count);
383 if ((flags == (INT32) STYP_BSS) || (flags == (INT32) (STYP_BSS | STYP_ABS))) {
384 /* Clear BSS section */
385 if (flags & Section) {
386 print_ld_msg(flags,quietmode,address,byte_count);
387 if (Mini_fill ((INT32) D_MEM,
389 (INT32) (byte_count+3)/4,
391 "\0\0\0") != SUCCESS) {
392 (void) fclose(coff_in); warning(EMFILL); return(FAILURE);
394 print_end_msg(flags,quietmode,address,byte_count);
396 } else if (flags & Section) { /* not a BSS or COmment */
397 if (flags == (INT32) (flags & Section)) {
398 fseek (coff_in, COFF_section_header.s_scnptr, FROM_BEGINNING);
399 while (byte_count > 0) {
400 temp_byte_count = MIN((INT32) byte_count, (INT32) sizeof(buffer));
401 if (fread((char *) buffer, (int) temp_byte_count, 1, coff_in) != 1) {
402 fclose(coff_in); warning (EMSCN); return (FAILURE);
404 print_ld_msg(flags, quietmode,address, temp_byte_count);
405 /* Write to 29K memory*/
406 if (Mini_write_req ((INT32) memory_space,
408 (INT32) (temp_byte_count+3)/4,
409 (INT16) 4, /* size */
412 (INT32) FALSE) != SUCCESS) {
416 address = address + temp_byte_count;
417 byte_count = byte_count - temp_byte_count;
419 print_end_msg(flags, quietmode, COFF_section_header.s_paddr,
420 COFF_section_header.s_size);
425 (void) fclose(coff_in);
428 } /* end Mini_loadcoff() */
437 if (string[0] != '-')
438 return (-1); /* not section options */
441 for (i=1; string[i] != '\0'; i++) {
445 Sections = Sections | STYP_TEXT;
449 Sections = Sections | STYP_DATA;
453 Sections = Sections | STYP_BSS;
457 Sections = Sections | STYP_LIT;
467 print_ld_msg(flags, mode, address, byte_count)
474 if (flags & (INT32) STYP_BSS)
475 fprintf(stderr, "Clearing ");
477 fprintf(stderr, "Loading ");
479 if ((flags == (INT32) STYP_TEXT) || (flags == (INT32) (STYP_TEXT|STYP_ABS)))
480 fprintf(stderr, "TEXT ");
481 else if (flags & (INT32) STYP_DATA)
482 fprintf(stderr, "DATA ");
483 else if (flags & (INT32) STYP_LIT)
484 fprintf(stderr, "LIT ");
485 else if (flags & (INT32) STYP_BSS)
486 fprintf(stderr, "BSS ");
487 fprintf(stderr, "section from 0x%08lx to 0x%08lx\r",
488 address, (ADDR32) (address+byte_count));
493 print_ign_msg(mode, address, byte_count)
499 fprintf(stderr, "Ignoring COMMENT section (%ld bytes) ...\n", byte_count);
503 print_end_msg(flags, mode,address,size)
510 if (flags & (INT32) STYP_BSS)
511 fprintf(stderr, "Cleared ");
513 fprintf(stderr, "Loaded ");
514 if (io_config.echo_mode == (INT32) TRUE) {
515 if (flags & (INT32) STYP_BSS)
516 fprintf(io_config.echo_file, "Cleared ");
518 fprintf(io_config.echo_file, "Loaded ");
521 if ((flags == (INT32) STYP_TEXT) ||
522 (flags == (INT32) (STYP_TEXT|STYP_ABS)))
523 fprintf(stderr, "TEXT ");
524 else if (flags & (INT32) STYP_DATA)
525 fprintf(stderr, "DATA ");
526 else if (flags & (INT32) STYP_LIT)
527 fprintf(stderr, "LIT ");
528 else if (flags & (INT32) STYP_BSS)
529 fprintf(stderr, "BSS ");
531 fprintf(stderr, "section from 0x%08lx to 0x%08lx\n",
532 address, (ADDR32) (address+size));
533 if (io_config.echo_mode == (INT32) TRUE) {
534 if ((flags == (INT32) STYP_TEXT) ||
535 (flags == (INT32) (STYP_TEXT|STYP_ABS)))
536 fprintf(io_config.echo_file, "TEXT ");
537 else if (flags & (INT32) STYP_DATA)
538 fprintf(io_config.echo_file, "DATA ");
539 else if (flags & (INT32) STYP_LIT)
540 fprintf(io_config.echo_file, "LIT ");
541 else if (flags & (INT32) STYP_BSS)
542 fprintf(io_config.echo_file, "BSS ");
544 fprintf(io_config.echo_file, "section from 0x%08lx to 0x%08lx\n",
545 address, (ADDR32) (address+size));