home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 9 / FreshFishVol9-CD2.bin / bbs / gnu / gdb-4.14-src.lha / gdb-4.14 / gdb / sparclite / aload.c next >
Encoding:
C/C++ Source or Header  |  1994-08-12  |  5.4 KB  |  259 lines

  1. /* Program to load an image into the SPARClite monitor board
  2.    Copyright 1993 Free Software Foundation, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Call with:
  19.  
  20.    aload PROG TTY
  21.  
  22. ie: aload hello /dev/ttya
  23.  
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <stdarg.h>
  28. #include <errno.h>
  29. #include <termios.h>
  30. #include <unistd.h>
  31. #include <fcntl.h>
  32.  
  33. #define min(A, B) (((A) < (B)) ? (A) : (B))
  34.  
  35. #include <sys/types.h>
  36. #include <bfd.h>
  37.  
  38. /* Where the code goes by default. */
  39.  
  40. #ifndef LOAD_ADDRESS
  41. #define LOAD_ADDRESS 0x40000000
  42. #endif
  43.  
  44. int quiet = 0;
  45.  
  46. static void
  47. usage()
  48. {
  49.   fprintf(stderr, "usage: aload [-q] file device\n");
  50.   exit (1);
  51. }
  52.  
  53. static void
  54. sys_error(const char *msg, ...)
  55. {
  56.   int e = errno;
  57.   va_list args;
  58.  
  59.   va_start(args, msg);
  60.   vfprintf(stderr, msg, args);
  61.   va_end(args);
  62.  
  63.   fprintf(stderr, ": %s\n", strerror(e));
  64.   exit(1);
  65. }
  66.  
  67. static void
  68. error(const char *msg, ...)
  69. {
  70.   va_list args;
  71.   
  72.   va_start(args, msg);
  73.   vfprintf(stderr, msg, args);
  74.   va_end(args);
  75.  
  76.   fputc('\n', stderr);
  77.   exit(1);
  78. }
  79.  
  80. static FILE *ttyf;
  81.  
  82. static void
  83. sendex(outtxt, outlen, intxt, inlen, id)
  84.      unsigned char *outtxt;
  85.      int outlen;
  86.      unsigned char *intxt;
  87.      int inlen;
  88.      char *id;
  89. {
  90.   char buf[100];
  91.   int cc;
  92.  
  93.   if (outlen > 0)
  94.     {
  95.       cc = write(fileno(ttyf), outtxt, outlen);
  96.       if (cc != outlen)
  97.     sys_error("Write %s failed", id);
  98.     }
  99.  
  100.   if (inlen > 0)
  101.     {
  102.       cc = read(fileno(ttyf), buf, inlen);    /* Get reply */
  103.       if (cc != inlen)
  104.     sys_error("Read %s reply failed", id);
  105.       if (bcmp(buf, intxt, inlen) != 0)
  106.     error("Bad reply to %s", id);
  107.     }
  108. }
  109.  
  110. main(argc, argv)
  111.      int argc;
  112.      char **argv;
  113. {
  114.   struct termios termios;
  115.   int cc, progsize, i;
  116.   unsigned char buf[10];
  117.   asection *section;
  118.   bfd *pbfd;
  119.   unsigned long entry;
  120.  
  121.   extern int optind;
  122.   int c;
  123.  
  124.   while ((c = getopt(argc, argv, "q")) != EOF) 
  125.     {
  126.       switch (c) 
  127.     {
  128.     case 'q':
  129.       quiet = 1;
  130.       break;
  131.     default:
  132.       usage();
  133.     }
  134.     }
  135.   argc -= optind;
  136.   argv += optind;
  137.  
  138.   if (argc != 2) {
  139.     usage();
  140.   }
  141.  
  142.   pbfd = bfd_openr(argv[0], 0);
  143.  
  144.   if (!pbfd)
  145.     sys_error("Open of PROG failed");
  146.  
  147. /* setup the tty.  Must be raw, no flow control, 9600 baud */
  148.  
  149.   ttyf = fopen(argv[1], "r+");
  150.   if (!ttyf)
  151.     sys_error("Open of TTY failed");
  152.   setbuf(ttyf, NULL);        /* Strictly unbuffered */
  153.  
  154.   if (tcgetattr(fileno(ttyf), &termios))
  155.     sys_error("tcgetattr failed");
  156.  
  157.   termios.c_iflag = 0;
  158.   termios.c_oflag = 0;
  159.   termios.c_cflag = CS8 | CREAD | CLOCAL;
  160.   termios.c_lflag = 0;
  161.   termios.c_cc[VMIN] = 1;
  162.   termios.c_cc[VTIME] = 0;
  163.  
  164.   if (cfsetospeed(&termios, B9600)
  165.       || cfsetispeed(&termios, B9600))
  166.     sys_error("cfset{i|o}speed failed");
  167.  
  168.   if (tcsetattr(fileno(ttyf), TCSANOW, &termios))
  169.     sys_error("tcsetattr failed");
  170.  
  171.   sendex("", 1, "\xaa", 1, "alive?");
  172.   sendex("\x55", 1, "\x55", 1, "alive");
  173.   if (!quiet)
  174.     printf("[SPARClite appears to be alive]\n");
  175.  
  176.   if (!bfd_check_format (pbfd, bfd_object)) 
  177.     error ("It doesn't seem to be an object file");
  178.  
  179.   for (section = pbfd->sections; section; section = section->next) 
  180.     {
  181.       if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
  182.     {
  183.       bfd_vma section_address;
  184.       unsigned long section_size;
  185.       const char *section_name;
  186.  
  187.       section_name = bfd_get_section_name (pbfd, section);
  188.  
  189.       section_address = bfd_get_section_vma (pbfd, section);
  190.       /* Adjust sections from a.out files, since they don't
  191.          carry their addresses with.  */
  192.       if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour)
  193.         section_address += LOAD_ADDRESS;
  194.       section_size = bfd_section_size (pbfd, section);
  195.  
  196.       if (!quiet)
  197.         printf("[Loading section %s at %x (%d bytes)]\n",
  198.            section_name,
  199.            section_address,
  200.            section_size);
  201.  
  202.       if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) /* Text, data or lit */
  203.         {
  204.           file_ptr fptr;
  205.  
  206.           fptr = 0;
  207.  
  208.           while (section_size > 0)
  209.         {
  210.           char buffer[1024];
  211.           int count, i;
  212.           unsigned char checksum;
  213.           static char inds[] = "|/-\\";
  214.           static int k = 0;
  215.  
  216.           count = min (section_size, 1024);
  217.  
  218.           bfd_get_section_contents (pbfd, section, buffer, fptr,
  219.                         count);
  220.  
  221.           checksum = 0;
  222.           for (i=0; i < count; i++)
  223.             checksum += buffer[i];
  224.  
  225.           if (!quiet) 
  226.             {
  227.               printf("\r%c", inds[k++ % 4]);
  228.               fflush(stdout);
  229.             }
  230.  
  231.           sendex("\001", 1, "\x5a", 1, "load command");
  232.           sendex(§ion_address, 4, NULL, 0, "load address");
  233.           sendex(&count, 4, NULL, 0, "program size");
  234.           sendex(buffer, count, &checksum, 1, "program");
  235.  
  236.           section_address += count;
  237.           fptr += count;
  238.           section_size -= count;
  239.         }
  240.         }
  241.       else            /* BSS */
  242.         {
  243.           if (!quiet)
  244.         printf ("Not loading BSS \n");
  245.         }
  246.     }
  247.     }
  248.  
  249.   entry = bfd_get_start_address (pbfd);
  250.  
  251.   if (!quiet) 
  252.     printf("[Starting %s at 0x%x]\n", argv[0], entry);
  253.  
  254.   sendex("\003", 1, NULL, 0, "exec command");
  255.   sendex(&entry, 4, "\x55", 1, "program start");
  256.  
  257.   exit(0);
  258. }
  259.