2000-03-21 J.T. Conklin <jtc@redback.com>
[platform/upstream/binutils.git] / gdb / sparcl-tdep.c
1 /* Target dependent code for the Fujitsu SPARClite for GDB, the GNU debugger.
2    Copyright 1994, 1995, 1996, 1999  Free Software Foundation, Inc.
3
4    This file is part of GDB.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #include "defs.h"
22 #include "gdbcore.h"
23 #include "breakpoint.h"
24 #include "target.h"
25 #include "serial.h"
26 #include <sys/types.h>
27
28 #if (!defined(__GO32__) && !defined(_WIN32)) || defined(__CYGWIN32__)
29 #define HAVE_SOCKETS
30 #include <sys/time.h>
31 #include <sys/socket.h>
32 #include <netinet/in.h>
33 #include <netdb.h>
34 #endif
35
36 static struct target_ops sparclite_ops;
37
38 static char *remote_target_name = NULL;
39 static serial_t remote_desc = NULL;
40 static int serial_flag;
41 #ifdef HAVE_SOCKETS
42 static int udp_fd = -1;
43 #endif
44
45 static serial_t open_tty PARAMS ((char *name));
46 static int send_resp PARAMS ((serial_t desc, char c));
47 static void close_tty PARAMS ((int ignore));
48 #ifdef HAVE_SOCKETS
49 static int recv_udp_buf PARAMS ((int fd, unsigned char *buf, int len, int timeout));
50 static int send_udp_buf PARAMS ((int fd, unsigned char *buf, int len));
51 #endif
52 static void sparclite_open PARAMS ((char *name, int from_tty));
53 static void sparclite_close PARAMS ((int quitting));
54 static void download PARAMS ((char *target_name, char *args, int from_tty,
55                               void (*write_routine) (bfd * from_bfd,
56                                                      asection * from_sec,
57                                                      file_ptr from_addr,
58                                                   bfd_vma to_addr, int len),
59                               void (*start_routine) (bfd_vma entry)));
60 static void sparclite_serial_start PARAMS ((bfd_vma entry));
61 static void sparclite_serial_write PARAMS ((bfd * from_bfd, asection * from_sec,
62                                             file_ptr from_addr,
63                                             bfd_vma to_addr, int len));
64 #ifdef HAVE_SOCKETS
65 static unsigned short calc_checksum PARAMS ((unsigned char *buffer,
66                                              int count));
67 static void sparclite_udp_start PARAMS ((bfd_vma entry));
68 static void sparclite_udp_write PARAMS ((bfd * from_bfd, asection * from_sec,
69                                          file_ptr from_addr, bfd_vma to_addr,
70                                          int len));
71 #endif
72 static void sparclite_download PARAMS ((char *filename, int from_tty));
73
74 #define DDA2_SUP_ASI            0xb000000
75 #define DDA1_SUP_ASI            0xb0000
76
77 #define DDA2_ASI_MASK           0xff000000
78 #define DDA1_ASI_MASK           0xff0000
79 #define DIA2_SUP_MODE           0x8000
80 #define DIA1_SUP_MODE           0x4000
81 #define DDA2_ENABLE             0x100
82 #define DDA1_ENABLE             0x80
83 #define DIA2_ENABLE             0x40
84 #define DIA1_ENABLE             0x20
85 #define DSINGLE_STEP            0x10    /* not used */
86 #define DDV_TYPE_MASK           0xc
87 #define DDV_TYPE_LOAD           0x0
88 #define DDV_TYPE_STORE          0x4
89 #define DDV_TYPE_ACCESS         0x8
90 #define DDV_TYPE_ALWAYS         0xc
91 #define DDV_COND                0x2
92 #define DDV_MASK                0x1
93
94 int
95 sparclite_insert_watchpoint (addr, len, type)
96      CORE_ADDR addr;
97      int len;
98      int type;
99 {
100   CORE_ADDR dcr;
101
102   dcr = read_register (DCR_REGNUM);
103
104   if (!(dcr & DDA1_ENABLE))
105     {
106       write_register (DDA1_REGNUM, addr);
107       dcr &= ~(DDA1_ASI_MASK | DDV_TYPE_MASK);
108       dcr |= (DDA1_SUP_ASI | DDA1_ENABLE);
109       if (type == 1)
110         {
111           write_register (DDV1_REGNUM, 0);
112           write_register (DDV2_REGNUM, 0xffffffff);
113           dcr |= (DDV_TYPE_LOAD & (~DDV_COND & ~DDV_MASK));
114         }
115       else if (type == 0)
116         {
117           write_register (DDV1_REGNUM, 0);
118           write_register (DDV2_REGNUM, 0xffffffff);
119           dcr |= (DDV_TYPE_STORE & (~DDV_COND & ~DDV_MASK));
120         }
121       else
122         {
123           write_register (DDV1_REGNUM, 0);
124           write_register (DDV2_REGNUM, 0xffffffff);
125           dcr |= (DDV_TYPE_ACCESS);
126         }
127       write_register (DCR_REGNUM, dcr);
128     }
129   else if (!(dcr & DDA2_ENABLE))
130     {
131       write_register (DDA2_REGNUM, addr);
132       dcr &= ~(DDA2_ASI_MASK & DDV_TYPE_MASK);
133       dcr |= (DDA2_SUP_ASI | DDA2_ENABLE);
134       if (type == 1)
135         {
136           write_register (DDV1_REGNUM, 0);
137           write_register (DDV2_REGNUM, 0xffffffff);
138           dcr |= (DDV_TYPE_LOAD & ~DDV_COND & ~DDV_MASK);
139         }
140       else if (type == 0)
141         {
142           write_register (DDV1_REGNUM, 0);
143           write_register (DDV2_REGNUM, 0xffffffff);
144           dcr |= (DDV_TYPE_STORE & ~DDV_COND & ~DDV_MASK);
145         }
146       else
147         {
148           write_register (DDV1_REGNUM, 0);
149           write_register (DDV2_REGNUM, 0xffffffff);
150           dcr |= (DDV_TYPE_ACCESS);
151         }
152       write_register (DCR_REGNUM, dcr);
153     }
154   else
155     return -1;
156
157   return 0;
158 }
159
160 int
161 sparclite_remove_watchpoint (addr, len, type)
162      CORE_ADDR addr;
163      int len;
164      int type;
165 {
166   CORE_ADDR dcr, dda1, dda2;
167
168   dcr = read_register (DCR_REGNUM);
169   dda1 = read_register (DDA1_REGNUM);
170   dda2 = read_register (DDA2_REGNUM);
171
172   if ((dcr & DDA1_ENABLE) && addr == dda1)
173     write_register (DCR_REGNUM, (dcr & ~DDA1_ENABLE));
174   else if ((dcr & DDA2_ENABLE) && addr == dda2)
175     write_register (DCR_REGNUM, (dcr & ~DDA2_ENABLE));
176   else
177     return -1;
178
179   return 0;
180 }
181
182 int
183 sparclite_insert_hw_breakpoint (addr, len)
184      CORE_ADDR addr;
185      int len;
186 {
187   CORE_ADDR dcr;
188
189   dcr = read_register (DCR_REGNUM);
190
191   if (!(dcr & DIA1_ENABLE))
192     {
193       write_register (DIA1_REGNUM, addr);
194       write_register (DCR_REGNUM, (dcr | DIA1_ENABLE | DIA1_SUP_MODE));
195     }
196   else if (!(dcr & DIA2_ENABLE))
197     {
198       write_register (DIA2_REGNUM, addr);
199       write_register (DCR_REGNUM, (dcr | DIA2_ENABLE | DIA2_SUP_MODE));
200     }
201   else
202     return -1;
203
204   return 0;
205 }
206
207 int
208 sparclite_remove_hw_breakpoint (addr, shadow)
209      CORE_ADDR addr;
210      int shadow;
211 {
212   CORE_ADDR dcr, dia1, dia2;
213
214   dcr = read_register (DCR_REGNUM);
215   dia1 = read_register (DIA1_REGNUM);
216   dia2 = read_register (DIA2_REGNUM);
217
218   if ((dcr & DIA1_ENABLE) && addr == dia1)
219     write_register (DCR_REGNUM, (dcr & ~DIA1_ENABLE));
220   else if ((dcr & DIA2_ENABLE) && addr == dia2)
221     write_register (DCR_REGNUM, (dcr & ~DIA2_ENABLE));
222   else
223     return -1;
224
225   return 0;
226 }
227
228 int
229 sparclite_check_watch_resources (type, cnt, ot)
230      int type;
231      int cnt;
232      int ot;
233 {
234   /* Watchpoints not supported on simulator.  */
235   if (strcmp (target_shortname, "sim") == 0)
236     return 0;
237
238   if (type == bp_hardware_breakpoint)
239     {
240       if (TARGET_HW_BREAK_LIMIT == 0)
241         return 0;
242       else if (cnt <= TARGET_HW_BREAK_LIMIT)
243         return 1;
244     }
245   else
246     {
247       if (TARGET_HW_WATCH_LIMIT == 0)
248         return 0;
249       else if (ot)
250         return -1;
251       else if (cnt <= TARGET_HW_WATCH_LIMIT)
252         return 1;
253     }
254   return -1;
255 }
256
257 CORE_ADDR
258 sparclite_stopped_data_address ()
259 {
260   CORE_ADDR dsr, dda1, dda2;
261
262   dsr = read_register (DSR_REGNUM);
263   dda1 = read_register (DDA1_REGNUM);
264   dda2 = read_register (DDA2_REGNUM);
265
266   if (dsr & 0x10)
267     return dda1;
268   else if (dsr & 0x20)
269     return dda2;
270   else
271     return 0;
272 }
273 \f
274 static serial_t
275 open_tty (name)
276      char *name;
277 {
278   serial_t desc;
279
280   desc = SERIAL_OPEN (name);
281   if (!desc)
282     perror_with_name (name);
283
284   if (baud_rate != -1)
285     {
286       if (SERIAL_SETBAUDRATE (desc, baud_rate))
287         {
288           SERIAL_CLOSE (desc);
289           perror_with_name (name);
290         }
291     }
292
293   SERIAL_RAW (desc);
294
295   SERIAL_FLUSH_INPUT (desc);
296
297   return desc;
298 }
299
300 /* Read a single character from the remote end, masking it down to 7 bits. */
301
302 static int
303 readchar (desc, timeout)
304      serial_t desc;
305      int timeout;
306 {
307   int ch;
308   char s[10];
309
310   ch = SERIAL_READCHAR (desc, timeout);
311
312   switch (ch)
313     {
314     case SERIAL_EOF:
315       error ("SPARClite remote connection closed");
316     case SERIAL_ERROR:
317       perror_with_name ("SPARClite communication error");
318     case SERIAL_TIMEOUT:
319       error ("SPARClite remote timeout");
320     default:
321       if (remote_debug > 0)
322         {
323           sprintf (s, "[%02x]", ch & 0xff);
324           puts_debug ("read -->", s, "<--");
325         }
326       return ch;
327     }
328 }
329
330 static void
331 debug_serial_write (desc, buf, len)
332      serial_t desc;
333      char *buf;
334      int len;
335 {
336   char s[10];
337
338   SERIAL_WRITE (desc, buf, len);
339   if (remote_debug > 0)
340     {
341       while (len-- > 0)
342         {
343           sprintf (s, "[%02x]", *buf & 0xff);
344           puts_debug ("Sent -->", s, "<--");
345           buf++;
346         }
347     }
348 }
349
350
351 static int
352 send_resp (desc, c)
353      serial_t desc;
354      char c;
355 {
356   debug_serial_write (desc, &c, 1);
357   return readchar (desc, remote_timeout);
358 }
359
360 static void
361 close_tty (ignore)
362      int ignore;
363 {
364   if (!remote_desc)
365     return;
366
367   SERIAL_CLOSE (remote_desc);
368
369   remote_desc = NULL;
370 }
371
372 #ifdef HAVE_SOCKETS
373 static int
374 recv_udp_buf (fd, buf, len, timeout)
375      int fd, len;
376      unsigned char *buf;
377      int timeout;
378 {
379   int cc;
380   fd_set readfds;
381
382   FD_ZERO (&readfds);
383   FD_SET (fd, &readfds);
384
385   if (timeout >= 0)
386     {
387       struct timeval timebuf;
388
389       timebuf.tv_sec = timeout;
390       timebuf.tv_usec = 0;
391       cc = select (fd + 1, &readfds, 0, 0, &timebuf);
392     }
393   else
394     cc = select (fd + 1, &readfds, 0, 0, 0);
395
396   if (cc == 0)
397     return 0;
398
399   if (cc != 1)
400     perror_with_name ("recv_udp_buf: Bad return value from select:");
401
402   cc = recv (fd, buf, len, 0);
403
404   if (cc < 0)
405     perror_with_name ("Got an error from recv: ");
406 }
407
408 static int
409 send_udp_buf (fd, buf, len)
410      int fd, len;
411      unsigned char *buf;
412 {
413   int cc;
414
415   cc = send (fd, buf, len, 0);
416
417   if (cc == len)
418     return;
419
420   if (cc < 0)
421     perror_with_name ("Got an error from send: ");
422
423   error ("Short count in send: tried %d, sent %d\n", len, cc);
424 }
425 #endif /* HAVE_SOCKETS */
426
427 static void
428 sparclite_open (name, from_tty)
429      char *name;
430      int from_tty;
431 {
432   struct cleanup *old_chain;
433   int c;
434   char *p;
435
436   if (!name)
437     error ("You need to specify what device or hostname is associated with the SparcLite board.");
438
439   target_preopen (from_tty);
440
441   unpush_target (&sparclite_ops);
442
443   if (remote_target_name)
444     free (remote_target_name);
445
446   remote_target_name = strsave (name);
447
448   /* We need a 'serial' or 'udp' keyword to disambiguate host:port, which can
449      mean either a serial port on a terminal server, or the IP address of a
450      SPARClite demo board.  If there's no colon, then it pretty much has to be
451      a local device (except for DOS... grrmble) */
452
453   p = strchr (name, ' ');
454
455   if (p)
456     {
457       *p++ = '\000';
458       while ((*p != '\000') && isspace (*p))
459         p++;
460
461       if (strncmp (name, "serial", strlen (name)) == 0)
462         serial_flag = 1;
463       else if (strncmp (name, "udp", strlen (name)) == 0)
464         serial_flag = 0;
465       else
466         error ("Must specify either `serial' or `udp'.");
467     }
468   else
469     {
470       p = name;
471
472       if (!strchr (name, ':'))
473         serial_flag = 1;        /* No colon is unambiguous (local device) */
474       else
475         error ("Usage: target sparclite serial /dev/ttyb\n\
476 or: target sparclite udp host");
477     }
478
479   if (serial_flag)
480     {
481       remote_desc = open_tty (p);
482
483       old_chain = make_cleanup ((make_cleanup_func) close_tty, 0);
484
485       c = send_resp (remote_desc, 0x00);
486
487       if (c != 0xaa)
488         error ("Unknown response (0x%x) from SparcLite.  Try resetting the board.",
489                c);
490
491       c = send_resp (remote_desc, 0x55);
492
493       if (c != 0x55)
494         error ("Sparclite appears to be ill.");
495     }
496   else
497     {
498 #ifdef HAVE_SOCKETS
499       struct hostent *he;
500       struct sockaddr_in sockaddr;
501       unsigned char buffer[100];
502       int cc;
503
504       /* Setup the socket.  Must be raw UDP. */
505
506       he = gethostbyname (p);
507
508       if (!he)
509         error ("No such host %s.", p);
510
511       udp_fd = socket (PF_INET, SOCK_DGRAM, 0);
512
513       old_chain = make_cleanup (close, udp_fd);
514
515       sockaddr.sin_family = PF_INET;
516       sockaddr.sin_port = htons (7000);
517       memcpy (&sockaddr.sin_addr.s_addr, he->h_addr, sizeof (struct in_addr));
518
519       if (connect (udp_fd, &sockaddr, sizeof (sockaddr)))
520         perror_with_name ("Connect failed");
521
522       buffer[0] = 0x5;
523       buffer[1] = 0;
524
525       send_udp_buf (udp_fd, buffer, 2);         /* Request version */
526       cc = recv_udp_buf (udp_fd, buffer, sizeof (buffer), 5);   /* Get response */
527       if (cc == 0)
528         error ("SPARClite isn't responding.");
529
530       if (cc < 3)
531         error ("SPARClite appears to be ill.");
532 #else
533       error ("UDP downloading is not supported for DOS hosts.");
534 #endif /* HAVE_SOCKETS */
535     }
536
537   printf_unfiltered ("[SPARClite appears to be alive]\n");
538
539   push_target (&sparclite_ops);
540
541   discard_cleanups (old_chain);
542
543   return;
544 }
545
546 static void
547 sparclite_close (quitting)
548      int quitting;
549 {
550   if (serial_flag)
551     close_tty (0);
552 #ifdef HAVE_SOCKETS
553   else if (udp_fd != -1)
554     close (udp_fd);
555 #endif
556 }
557
558 #define LOAD_ADDRESS 0x40000000
559
560 static void
561 download (target_name, args, from_tty, write_routine, start_routine)
562      char *target_name;
563      char *args;
564      int from_tty;
565      void (*write_routine) PARAMS ((bfd * from_bfd, asection * from_sec,
566                              file_ptr from_addr, bfd_vma to_addr, int len));
567      void (*start_routine) PARAMS ((bfd_vma entry));
568 {
569   struct cleanup *old_chain;
570   asection *section;
571   bfd *pbfd;
572   bfd_vma entry;
573   int i;
574 #define WRITESIZE 1024
575   char *filename;
576   int quiet;
577   int nostart;
578
579   quiet = 0;
580   nostart = 0;
581   filename = NULL;
582
583   while (*args != '\000')
584     {
585       char *arg;
586
587       while (isspace (*args))
588         args++;
589
590       arg = args;
591
592       while ((*args != '\000') && !isspace (*args))
593         args++;
594
595       if (*args != '\000')
596         *args++ = '\000';
597
598       if (*arg != '-')
599         filename = arg;
600       else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
601         quiet = 1;
602       else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
603         nostart = 1;
604       else
605         error ("unknown option `%s'", arg);
606     }
607
608   if (!filename)
609     filename = get_exec_file (1);
610
611   pbfd = bfd_openr (filename, gnutarget);
612   if (pbfd == NULL)
613     {
614       perror_with_name (filename);
615       return;
616     }
617   old_chain = make_cleanup ((make_cleanup_func) bfd_close, pbfd);
618
619   if (!bfd_check_format (pbfd, bfd_object))
620     error ("\"%s\" is not an object file: %s", filename,
621            bfd_errmsg (bfd_get_error ()));
622
623   for (section = pbfd->sections; section; section = section->next)
624     {
625       if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
626         {
627           bfd_vma section_address;
628           bfd_size_type section_size;
629           file_ptr fptr;
630           const char *section_name;
631
632           section_name = bfd_get_section_name (pbfd, section);
633
634           section_address = bfd_get_section_vma (pbfd, section);
635
636           /* Adjust sections from a.out files, since they don't
637              carry their addresses with.  */
638           if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour)
639             {
640               if (strcmp (section_name, ".text") == 0)
641                 section_address = bfd_get_start_address (pbfd);
642               else if (strcmp (section_name, ".data") == 0)
643                 {
644                   /* Read the first 8 bytes of the data section.
645                      There should be the string 'DaTa' followed by
646                      a word containing the actual section address. */
647                   struct data_marker
648                     {
649                       char signature[4];        /* 'DaTa' */
650                       unsigned char sdata[4];   /* &sdata */
651                     }
652                   marker;
653                   bfd_get_section_contents (pbfd, section, &marker, 0,
654                                             sizeof (marker));
655                   if (strncmp (marker.signature, "DaTa", 4) == 0)
656                     {
657                       if (TARGET_BYTE_ORDER == BIG_ENDIAN)
658                         section_address = bfd_getb32 (marker.sdata);
659                       else
660                         section_address = bfd_getl32 (marker.sdata);
661                     }
662                 }
663             }
664
665           section_size = bfd_get_section_size_before_reloc (section);
666
667           if (!quiet)
668             printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n",
669                              bfd_get_section_name (pbfd, section),
670                              section_address,
671                              section_size);
672
673           fptr = 0;
674           while (section_size > 0)
675             {
676               int count;
677               static char inds[] = "|/-\\";
678               static int k = 0;
679
680               QUIT;
681
682               count = min (section_size, WRITESIZE);
683
684               write_routine (pbfd, section, fptr, section_address, count);
685
686               if (!quiet)
687                 {
688                   printf_unfiltered ("\r%c", inds[k++ % 4]);
689                   gdb_flush (gdb_stdout);
690                 }
691
692               section_address += count;
693               fptr += count;
694               section_size -= count;
695             }
696         }
697     }
698
699   if (!nostart)
700     {
701       entry = bfd_get_start_address (pbfd);
702
703       if (!quiet)
704         printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry);
705
706       start_routine (entry);
707     }
708
709   do_cleanups (old_chain);
710 }
711
712 static void
713 sparclite_serial_start (entry)
714      bfd_vma entry;
715 {
716   char buffer[5];
717   int i;
718
719   buffer[0] = 0x03;
720   store_unsigned_integer (buffer + 1, 4, entry);
721
722   debug_serial_write (remote_desc, buffer, 1 + 4);
723   i = readchar (remote_desc, remote_timeout);
724   if (i != 0x55)
725     error ("Can't start SparcLite.  Error code %d\n", i);
726 }
727
728 static void
729 sparclite_serial_write (from_bfd, from_sec, from_addr, to_addr, len)
730      bfd *from_bfd;
731      asection *from_sec;
732      file_ptr from_addr;
733      bfd_vma to_addr;
734      int len;
735 {
736   char buffer[4 + 4 + WRITESIZE];       /* addr + len + data */
737   unsigned char checksum;
738   int i;
739
740   store_unsigned_integer (buffer, 4, to_addr);  /* Address */
741   store_unsigned_integer (buffer + 4, 4, len);  /* Length */
742
743   bfd_get_section_contents (from_bfd, from_sec, buffer + 8, from_addr, len);
744
745   checksum = 0;
746   for (i = 0; i < len; i++)
747     checksum += buffer[8 + i];
748
749   i = send_resp (remote_desc, 0x01);
750
751   if (i != 0x5a)
752     error ("Bad response from load command (0x%x)", i);
753
754   debug_serial_write (remote_desc, buffer, 4 + 4 + len);
755   i = readchar (remote_desc, remote_timeout);
756
757   if (i != checksum)
758     error ("Bad checksum from load command (0x%x)", i);
759 }
760
761 #ifdef HAVE_SOCKETS
762
763 static unsigned short
764 calc_checksum (buffer, count)
765      unsigned char *buffer;
766      int count;
767 {
768   unsigned short checksum;
769
770   checksum = 0;
771   for (; count > 0; count -= 2, buffer += 2)
772     checksum += (*buffer << 8) | *(buffer + 1);
773
774   if (count != 0)
775     checksum += *buffer << 8;
776
777   return checksum;
778 }
779
780 static void
781 sparclite_udp_start (entry)
782      bfd_vma entry;
783 {
784   unsigned char buffer[6];
785   int i;
786
787   buffer[0] = 0x3;
788   buffer[1] = 0;
789   buffer[2] = entry >> 24;
790   buffer[3] = entry >> 16;
791   buffer[4] = entry >> 8;
792   buffer[5] = entry;
793
794   send_udp_buf (udp_fd, buffer, 6);     /* Send start addr */
795   i = recv_udp_buf (udp_fd, buffer, sizeof (buffer), -1);       /* Get response */
796
797   if (i < 1 || buffer[0] != 0x55)
798     error ("Failed to take start address.");
799 }
800
801 static void
802 sparclite_udp_write (from_bfd, from_sec, from_addr, to_addr, len)
803      bfd *from_bfd;
804      asection *from_sec;
805      file_ptr from_addr;
806      bfd_vma to_addr;
807      int len;
808 {
809   unsigned char buffer[2000];
810   unsigned short checksum;
811   static int pkt_num = 0;
812   static unsigned long old_addr = -1;
813   int i;
814
815   while (1)
816     {
817       if (to_addr != old_addr)
818         {
819           buffer[0] = 0x1;      /* Load command */
820           buffer[1] = 0x1;      /* Loading address */
821           buffer[2] = to_addr >> 24;
822           buffer[3] = to_addr >> 16;
823           buffer[4] = to_addr >> 8;
824           buffer[5] = to_addr;
825
826           checksum = 0;
827           for (i = 0; i < 6; i++)
828             checksum += buffer[i];
829           checksum &= 0xff;
830
831           send_udp_buf (udp_fd, buffer, 6);
832           i = recv_udp_buf (udp_fd, buffer, sizeof buffer, -1);
833
834           if (i < 1)
835             error ("Got back short checksum for load addr.");
836
837           if (checksum != buffer[0])
838             error ("Got back bad checksum for load addr.");
839
840           pkt_num = 0;          /* Load addr resets packet seq # */
841           old_addr = to_addr;
842         }
843
844       bfd_get_section_contents (from_bfd, from_sec, buffer + 6, from_addr,
845                                 len);
846
847       checksum = calc_checksum (buffer + 6, len);
848
849       buffer[0] = 0x1;          /* Load command */
850       buffer[1] = 0x2;          /* Loading data */
851       buffer[2] = pkt_num >> 8;
852       buffer[3] = pkt_num;
853       buffer[4] = checksum >> 8;
854       buffer[5] = checksum;
855
856       send_udp_buf (udp_fd, buffer, len + 6);
857       i = recv_udp_buf (udp_fd, buffer, sizeof buffer, 3);
858
859       if (i == 0)
860         {
861           fprintf_unfiltered (gdb_stderr, "send_data: timeout sending %d bytes to address 0x%x retrying\n", len, to_addr);
862           continue;
863         }
864
865       if (buffer[0] != 0xff)
866         error ("Got back bad response for load data.");
867
868       old_addr += len;
869       pkt_num++;
870
871       return;
872     }
873 }
874
875 #endif /* HAVE_SOCKETS */
876
877 static void
878 sparclite_download (filename, from_tty)
879      char *filename;
880      int from_tty;
881 {
882   if (!serial_flag)
883 #ifdef HAVE_SOCKETS
884     download (remote_target_name, filename, from_tty, sparclite_udp_write,
885               sparclite_udp_start);
886 #else
887     abort ();                   /* sparclite_open should prevent this! */
888 #endif
889   else
890     download (remote_target_name, filename, from_tty, sparclite_serial_write,
891               sparclite_serial_start);
892 }
893 \f
894 /* Set up the sparclite target vector.  */
895
896 static void
897 init_sparclite_ops (void)
898 {
899   sparclite_ops.to_shortname = "sparclite";
900   sparclite_ops.to_longname = "SPARClite download target";
901   sparclite_ops.to_doc = "Download to a remote SPARClite target board via serial of UDP.\n\
902 Specify the device it is connected to (e.g. /dev/ttya).";
903   sparclite_ops.to_open = sparclite_open;
904   sparclite_ops.to_close = sparclite_close;
905   sparclite_ops.to_load = sparclite_download;
906   sparclite_ops.to_stratum = download_stratum;
907   sparclite_ops.to_magic = OPS_MAGIC;
908 }
909
910 void
911 _initialize_sparcl_tdep ()
912 {
913   init_sparclite_ops ();
914   add_target (&sparclite_ops);
915 }