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