* configure.in (--enable-netrom): New configuration option.
[deliverable/binutils-gdb.git] / gdb / remote-nrom.c
CommitLineData
33bc979d
SS
1/* Remote debugging with the XLNT Designs, Inc (XDI) NetROM.
2 Copyright 1990, 1991, 1992, 1995 Free Software Foundation, Inc.
3 Contributed by:
4 Roger Moyers
5 XLNT Designs, Inc.
6 15050 Avenue of Science, Suite 106
7 San Diego, CA 92128
8 (619)487-9320
9 roger@xlnt.com
10 Adapted from work done at Cygnus Support in remote-nindy.c,
11 later merged in by Stan Shebs at Cygnus.
12
13This file is part of GDB.
14
15This program is free software; you can redistribute it and/or modify
16it under the terms of the GNU General Public License as published by
17the Free Software Foundation; either version 2 of the License, or
18(at your option) any later version.
19
20This program is distributed in the hope that it will be useful,
21but WITHOUT ANY WARRANTY; without even the implied warranty of
22MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23GNU General Public License for more details.
24
25You should have received a copy of the GNU General Public License
26along with this program; if not, write to the Free Software
27Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
28
29#include "defs.h"
30#include "gdbcmd.h"
31#include <string.h>
32#include "inferior.h"
33#include "wait.h"
34#include "value.h"
35#include <ctype.h>
36#include <fcntl.h>
37#include <signal.h>
38#include <errno.h>
39#include <stropts.h>
40#include <sys/types.h>
41#include <sys/socket.h>
42#include <sys/ioctl.h>
43#include <netinet/in.h>
44#include <netdb.h>
45#include <unistd.h>
46#include "terminal.h"
47#include "target.h"
48#include "gdbcore.h"
49
50/* Packet header found on every packet sent to/from GDB. */
51
52typedef struct gpkthdr {
53 unsigned char csum; /* Check sum */
54 unsigned char seq_num; /* Sequence number */
55 unsigned short len; /* Number of bytes in packet */
56 unsigned char cmd; /* GDB command */
57 unsigned char pad[3];
58 unsigned long addr; /* Address if needed */
59 unsigned long datalen; /* # of bytes to read/write */
60} GPKTHDR;
61
62#define GDB_START_DELIMITER '['
63#define GDB_END_DELIMITER ']'
64
65/* GDB requests. */
66
67#define GDB_QUERY_CMD 0x01
68#define GDB_STATUS 0x02
69#define GDB_READ_REGS 0x03
70#define GDB_WRITE_REGS 0x04
71#define GDB_READ_MEM 0x05
72#define GDB_WRITE_MEM 0x06
73#define GDB_CONTINUE 0x07
74#define GDB_STEP 0x08
75
76/* Responses. */
77
78#define GDB_ACK 0x11
79#define GDB_NACK 0x12
80#define GDB_READ_REG_RESP 0x13
81#define GDB_READ_MEM_RESP 0x14
82#define GDB_WRITE_REG_RESP 0x15
83#define GDB_WRITE_MEM_RESP 0x16
84
85#define GDB_BP_TRAP "05"
86#define GDB_BUSERR_TRAP "10"
87#define GDB_ILLOP_TRAP "40"
88
89#define GDB_ACK_VALUE "OK"
90
91/* Default ports used to talk with the NetROM. */
92
93#define DEFAULT_NETROM_TARGET_PORT 1235
94#define DEFAULT_NETROM_LOAD_PORT 1236
95#define DEFAULT_NETROM_CONTROL_PORT 1237
96
97#define UC(b) (((long)b)&0xff)
98
99#define NROM_BUF_SIZE 2048
100#define MAX_SEND_ATTEMPTS 10
101#define READ_BUF_SIZE 2048
102
103/* Definitions for filetype. */
104
105#define BINARY_FTYPE 0
106#define MOTO_SREC 1
107#define INTEL_HEX 2
108
109#if 0 /* for debugging, if anyone cares */
110static char *GCMDTYPE[] = {
111 "ZERO",
112 "GDB_QUERY",
113 "GDB_STATUS",
114 "GDB_READ_REGS",
115 "GDB_WRITE_REGS",
116 "GDB_READ_MEM",
117 "GDB_WRITE_MEM",
118 "GDB_CONTINUE",
119 "GDB_STEP",
120 "CMD9",
121 "CMDA",
122 "CMDB",
123 "CMDC",
124 "CMDD",
125 "CMDE",
126 "CMDF",
127 "RESP0",
128 "GDB_ACK",
129 "GDB_NACK",
130 "GDB_READ_REG_RESP",
131 "GDB_READ_MEM_RESP",
132 "GDB_WRITE_REG_RESP",
133 "GDB_WRITE_MEM_RESP"
134};
135#endif
136
137static void nrom_attach PARAMS ((char *, int));
138
139static int nrom_can_run PARAMS ((void));
140
141static void nrom_close PARAMS ((int));
142
143static void nrom_create_inferior PARAMS ((char *, char *, char **));
144
145static void nrom_detach PARAMS ((char *, int));
146
147static void nrom_fetch_registers PARAMS ((int));
148
149static void nrom_files_info PARAMS ((struct target_ops *));
150
151static void nrom_kill PARAMS ((void));
152
153static void nrom_load PARAMS ((char *, int));
154
155static void nrom_mourn PARAMS ((void));
156
157static void nrom_open PARAMS ((char *,int));
158
159static void nrom_resume PARAMS ((int, int, enum target_signal));
160
161static void nrom_prepare_to_store PARAMS ((void));
162
163static void nrom_store_registers PARAMS ((int));
164
165static int nrom_wait PARAMS ((int pid, struct target_waitstatus *status));
166
167static int nrom_xfer_inferior_memory PARAMS ((CORE_ADDR, char *, int, int,
168 struct target_ops *));
169
170static int nrom_write_inferior_memory PARAMS ((CORE_ADDR, char *, int));
171
172static int nrom_read_inferior_memory PARAMS ((CORE_ADDR, char *, int));
173
174/* New commands. */
175
176static void nrom_set_target_port PARAMS ((char *, int));
177
178static void nrom_set_control_port PARAMS ((char *, int));
179
180static void nrom_set_load_port PARAMS ((char *, int));
181
182static void nrom_set_ipaddr PARAMS ((char *, int));
183
184static void nrom_set_filetype PARAMS ((char *, int));
185
186static void nrom_show_status PARAMS ((char *, int));
187
188static void nrom_passthru PARAMS ((char *, int));
189
190/* Packet functions. */
191
192static void build_pkt PARAMS ((int, unsigned char *, long,
193 unsigned char *, unsigned long, unsigned long,
194 int));
195
196static int compute_csum PARAMS ((unsigned char *, int));
197
198#if 0
199static void dump_pkt PARAMS ((GPKTHDR *, unsigned char *));
200#endif
201
202static int get_seq_number PARAMS ((void));
203
204static char *hex2mem PARAMS ((char *, char *, int));
205
206static char *mem2hex PARAMS ((char *, char *, int));
207
208static void nrom_send PARAMS ((int, char *, int, long, long, char *));
209
210static void send_query_cmd PARAMS ((void));
211
212static int send_pkt PARAMS ((int, char *, int, long, int));
213
214static int read_pkt PARAMS ((char *));
215
216static void send_query_cmd PARAMS ((void));
217
218static int tohex PARAMS ((int));
219
220static int parse_pkt PARAMS ((unsigned char *, GPKTHDR *, char *));
221
222static int writen PARAMS ((int, char *, int));
223
224/* Private globals. */
225
226/* We talk to the NetROM over these sockets. */
227
228static int nrom_load_sock = -1;
229static int nrom_targ_sock = -1;
230static int nrom_ctrl_sock = -1;
231
232/* For binding to the socket we ned a sockaddr_in structure. */
233
234static struct sockaddr_in nrom_sin;
235
236/* The IP Address of the NetROM is needed so we know who to talk to. */
237
238static unsigned long nrom_ipaddr = 0;
239
240static int load_port = DEFAULT_NETROM_LOAD_PORT;
241static int target_port = DEFAULT_NETROM_TARGET_PORT;
242static int control_port = DEFAULT_NETROM_CONTROL_PORT;
243
244static int nrom_filetype = BINARY_FTYPE;
245
246static unsigned char host_seq_num = 0;
247
248static char hexchars[] = "0123456789abcdef";
249
250static char freadbuf[READ_BUF_SIZE];
251
252static char readbuf[NROM_BUF_SIZE];
253static int bufdata = 0;
254static int bufindex = 0;
255
256static char workbuf[NROM_BUF_SIZE];
257static char sendbuf[NROM_BUF_SIZE];
258
259/* Forward data declaration. */
260
261extern struct target_ops nrom_ops;
262
263/* This routine builds a packet to send to gdb running on the host. */
264
265static void
266build_pkt (cmd, data, datalen, pkt, addr, len, seq)
267 int cmd;
268 unsigned char *data;
269 long datalen;
270 unsigned char *pkt;
271 unsigned long addr;
272 unsigned long len;
273 int seq;
274{
275 GPKTHDR phdr;
276 char *dptr;
277 char *pktptr;
278 unsigned char csum;
279 int plen;
280
281 phdr.csum = 0;
282 phdr.len = sizeof(GPKTHDR) + datalen;
283 phdr.seq_num = seq;
284 phdr.cmd = cmd;
285 phdr.pad[0] = phdr.pad[1] = phdr.pad[2] = 0;
286 phdr.addr = addr;
287 phdr.datalen = len;
288 /* Convert packet header to ASCII. */
289 dptr = mem2hex ((char *) &phdr, pkt, sizeof(GPKTHDR));
290
291 /* Calculate pkt length now that it is converted. */
292 plen = (int) ((unsigned long)dptr - (unsigned long)pkt) + datalen;
293 /* Put data in packet. */
294 if (datalen > 0)
295 memcpy (dptr, data, datalen);
296
297 /* Compute checksum. For computing checksum we skip first two bytes
298 since this is where the checksum will go. */
299 pktptr = pkt + 2;
300 csum = compute_csum (pktptr, plen - 2);
301 *pkt++ = hexchars[csum >> 4];
302 *pkt++ = hexchars[csum % 16];
303 dptr += datalen;
304 *dptr = '\0';
305}
306
307static int
308compute_csum (data, len)
309 unsigned char *data;
310 int len;
311{
312 unsigned char csum;
313
314 csum = 0;
315 while (len > 0)
316 {
317 csum += *data++;
318 --len;
319 }
320 return csum;
321}
322
323#if 0 /* for debugging, if anyone cares */
324static void
325dump_pkt (hdr, data)
326 GPKTHDR *hdr;
327 unsigned char *data;
328{
329 int i;
330
331 printf_filtered ("PACKET: csum = %x,seq = %d,len = %d\n",hdr->csum,hdr->seq_num,
332 hdr->len);
333
334 printf_filtered ("cmd = %s,addr = %x, datalen = %d\n", GCMDTYPE[hdr->cmd],
335 hdr->addr,hdr->datalen);
336 if (hdr->datalen)
337 {
338 for (i = 0; i < hdr->datalen * 2; i++)
339 printf_filtered ("%x",data[i]);
340 printf_filtered ("\n");
341 }
342}
343#endif
344
345static int
346get_seq_number()
347{
348 return host_seq_num++;
349}
350
351int
352hex (ch)
353 int ch;
354{
355 if ((ch >= 'a') && (ch <= 'f'))
356 return (ch - 'a' + 10);
357 if((ch >= 'A') && (ch <= 'F'))
358 return ((ch - 'A') + 10);
359 if ((ch >= '0') && (ch <= '9'))
360 return (ch - '0');
361 return 0;
362}
363
364/* Convert the hex array pointed to by buf into binary to be placed in mem
365 return a pointer to the character AFTER the last byte written. */
366
367static char*
368hex2mem(buf, mem, count)
369 char* buf;
370 char* mem;
371 int count;
372{
373 int i;
374 unsigned char ch;
375
376 for (i = 0; i < count; i++)
377 {
378 ch = hex(*buf++) << 4;
379 ch = ch + hex(*buf++);
380 *mem++ = ch;
381 }
382 return mem;
383}
384
385/* Convert the memory pointed to by mem into hex, placing result in buf
386 return a pointer to the last char put in buf (null) */
387
388static char *
389mem2hex (mem, buf, count)
390 char* mem;
391 char* buf;
392 int count;
393{
394 int i;
395 unsigned char ch;
396
397 for (i = 0; i < count; i++)
398 {
399 ch = *mem++;
400 *buf++ = hexchars[ch >> 4];
401 *buf++ = hexchars[ch % 16];
402 }
403 *buf = 0;
404 return buf;
405}
406
407static int
408nrom_control_send (s, nbytes)
409 char *s;
410 int nbytes;
411{
412 long len;
413 char buf[10];
414
415 /* clear leading characters */
416 /* FIXME: The ioctl uses here seem bogus to me. -sts */
417 len = 1;
418 while (len > 0)
419 {
420 if (ioctl (nrom_ctrl_sock, FIONREAD, &len) < 0)
421 {
422 perror ("nrom_control_send ioctl");
423 return (-1);
424 }
425 if (len > 0)
426 {
427 if (read (nrom_ctrl_sock, buf, 1) < 0)
428 {
429 perror ("nrom_control_send read");
430 return (-1);
431 }
432 }
433 }
434
435 if (remote_debug)
436 printf_filtered ("nrom_control_send: sending '%s' (%d bytes) to NetROM\n",
437 s, nbytes);
438
439 if (writen (nrom_ctrl_sock, s, nbytes) < 0)
440 {
441 perror ("nrom_control_send");
442 return (-1);
443 }
444
445 /* clear trailing characters */
446 len = 1;
447 while (len > 0)
448 {
449 if (ioctl (nrom_ctrl_sock, FIONREAD, &len) < 0)
450 {
451 perror ("nrom_control_send ioctl");
452 return (-1);
453 }
454 if (len > 0)
455 {
456 if (read (nrom_ctrl_sock, buf, 1) < 0)
457 {
458 perror ("nrom_control_send read");
459 return (-1);
460 }
461 }
462 }
463 return 0;
464}
465
466static void
467nrom_kill ()
468{
469}
470
471/* Download a file specified in ARGS to the netROM. */
472
473static void
474nrom_load (args, fromtty)
475 char *args;
476 int fromtty;
477{
478 int fd, rd_amt, fsize;
479 struct sockaddr_in sin;
480 bfd *pbfd;
481 asection *section;
482 char *downloadstring = "download 0\n";
483
484 /* Tell the netrom to get ready to download. */
485 if (nrom_control_send (downloadstring, strlen (downloadstring)) < 0)
486 error ("nrom_load: control_send() of `%s' failed", downloadstring);
487
488 /* Wait for the download daemon to start up. */
489 sleep (1);
490
491 nrom_load_sock = socket (AF_INET, SOCK_STREAM, 0);
492 if (nrom_load_sock == -1)
493 error ("Could not create download socket, error %d", errno);
494
495 memset (&sin, 0, sizeof(struct sockaddr_in));
496 sin.sin_family = AF_INET;
497 sin.sin_port = htons (load_port);
498 sin.sin_addr.s_addr = htonl (nrom_ipaddr);
499
500 if (connect (nrom_load_sock, &sin, sizeof(sin)) == -1)
501 error ("Connect failed, error %d", errno);
502
503 pbfd = bfd_openr (args, 0);
504
505 if (pbfd)
506 {
507 if (!bfd_check_format (pbfd, bfd_object))
508 error ("\"%s\": not in executable format: %s",
509 args, bfd_errmsg (bfd_get_error ()));
510
511 for (section = pbfd->sections; section; section = section->next)
512 {
513 if (bfd_get_section_flags (pbfd, section) & SEC_ALLOC)
514 {
515 bfd_vma section_address;
516 unsigned long section_size;
517 const char *section_name;
518
519 section_name = bfd_get_section_name (pbfd, section);
520 section_address = bfd_get_section_vma (pbfd, section);
521 section_size = bfd_section_size (pbfd, section);
522
523 if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
524 {
525 file_ptr fptr;
526
527 printf_filtered ("[Loading section %s at %x (%d bytes)]\n",
528 section_name, section_address,
529 section_size);
530
531 fptr = 0;
532
533 while (section_size > 0)
534 {
535 char buffer[1024];
536 int count;
537
538 count = min (section_size, 1024);
539
540 bfd_get_section_contents (pbfd, section, buffer, fptr,
541 count);
542
543 writen (nrom_load_sock, buffer, count);
544 section_address += count;
545 fptr += count;
546 section_size -= count;
547 }
548 }
549 else /* BSS and such */
550 {
551 printf_filtered ("[section %s: not loading]\n",
552 section_name);
553 }
554 }
555 }
556 }
557 else
558 error ("\"%s\": Could not open", args);
559
560 close (nrom_load_sock);
561}
562
563/* This is called not only when we first attach, but also when the
564 user types "run" after having attached. */
565
566static void
567nrom_create_inferior (execfile, args, env)
568 char *execfile;
569 char *args;
570 char **env;
571{
572}
573
574/* Open a connection to the remote NetROM devices. */
575
576static void
577nrom_open (name, from_tty)
578 char *name;
579 int from_tty;
580{
581 int errn;
582
583 if (name)
584 nrom_set_ipaddr (name, from_tty);
585 else if (nrom_ipaddr == 0)
586 error (
587"To open a NetROM connection, you must specify the hostname\n\
588or IP address of the NetROM device you wish to use.");
589
590 push_target (&nrom_ops);
591
592 /* Create the socket used for talking with the target. */
593 nrom_targ_sock = socket (AF_INET, SOCK_STREAM, 0);
594
595 /* Bind the socket. */
596 nrom_sin.sin_family = AF_INET;
597 nrom_sin.sin_port = htons (target_port);
598 nrom_sin.sin_addr.S_un.S_addr = htonl (nrom_ipaddr);
599
600 /* Connect to the remote host. */
601 if (connect (nrom_targ_sock, &nrom_sin, sizeof(nrom_sin)) == -1)
602 error ("Connect failed, error %d", errno);
603
604 /* Create the socket used for talking with the debugger services. */
605 nrom_ctrl_sock = socket (AF_INET, SOCK_STREAM, 0);
606
607 /* Bind the socket. */
608 nrom_sin.sin_family = AF_INET;
609 nrom_sin.sin_port = htons (control_port);
610 nrom_sin.sin_addr.S_un.S_addr = htonl (nrom_ipaddr);
611
612 /* Connect to the remote host. */
613 if (connect (nrom_ctrl_sock, &nrom_sin, sizeof(nrom_sin)) == -1)
614 {
615 errn = errno;
616 close (nrom_targ_sock);
617 error ("Connect control_socket failed, error %d", errn);
618 }
619
620 if (from_tty)
621 {
622 unsigned char *i;
623
624 printf_filtered ("Connected to NetROM device \"%s\"", name);
625 i = (unsigned char *) &nrom_ipaddr;
626 printf_filtered (" (%d.%d.%d.%d)\n",
627 UC(i[0]), UC(i[1]), UC(i[2]), UC(i[3]));
628 }
629}
630
631static int
632nrom_can_run ()
633{
634 return 1;
635}
636
637/* Close out all files and local state before this target loses control. */
638
639static void
640nrom_close (quitting)
641 int quitting;
642{
643}
644
645/* Attach to the target that is already loaded and possibly running */
646
647static void
648nrom_attach (args, from_tty)
649 char *args;
650 int from_tty;
651{
652 int nwaiting;
653 char buf[10];
654
655 if (from_tty)
656 printf_filtered ("Attaching to NetROM\n");
657
658 /* clear any pending data on the socket */
659 printf_filtered ("Waiting for pending data to arrive... ");
660 fflush(stdout);
661 sleep(1);
662 printf_filtered ("that's long enough!\n");
663 while (1)
664 {
665 if (ioctl(nrom_targ_sock, FIONREAD, &nwaiting) != 0)
666 {
667 /* couldn't determine data left */
668 perror("nrom_attach: ioctl FIONREAD");
669 break;
670 }
671 else if (nwaiting > 0)
672 {
673 /* flush incoming data */
674 while (nwaiting != 0)
675 {
676 if (read (nrom_targ_sock, buf, 1) < 0)
677 {
678 perror("nrom_attach: read");
679 exit(1);
680 }
681 if (remote_debug > 2)
682 putc(buf[0], stdout);
683 nwaiting--;
684 }
685 }
686 else
687 {
688 /* no more data */
689 break;
690 }
691 }
692 printf_filtered ("Pending data removed\n");
693
694 /* We will get a task spawn event immediately. */
695 send_query_cmd ();
696 target_has_execution = 1;
697/*
698 start_remote();
699*/
700}
701
702/* Terminate the open connection to the remote debugger. Use this
703 when you want to detach and do something else with your gdb. */
704
705static void
706nrom_detach (args, from_tty)
707 char *args;
708 int from_tty;
709{
710 pop_target ();
711 if (from_tty)
712 printf_filtered ("Ending remote debugging\n");
713}
714
715/* Tell the remote machine to resume. */
716
717static void
718nrom_prepare_to_store()
719{
720}
721
722static void
723nrom_resume (pid, step, siggnal)
724 int pid, step;
725 enum target_signal siggnal;
726{
727 if (step)
728 send_pkt (GDB_STEP, NULL, 0, 0, 0);
729 else
730 send_pkt (GDB_CONTINUE, NULL, 0, 0, 0);
731}
732
733/* Wait until the remote machine stops, then return,
734 storing status in STATUS just as `wait' would. */
735
736static int
737nrom_wait (pid, status)
738 int pid;
739 struct target_waitstatus *status;
740{
741 static char pkt[NROM_BUF_SIZE], inbuf[NROM_BUF_SIZE];
742 GPKTHDR phdr;
743
744 status->kind = TARGET_WAITKIND_EXITED;
745 status->value.integer = 0;
746
747 while (1)
748 {
749 if (read_pkt (pkt) == -1)
750 continue;
751
752 if (parse_pkt (pkt, &phdr, inbuf) < 0)
753 {
754 if (remote_debug)
755 printf_filtered ("Bad packet in nrom_wait\n");
756 send_query_cmd ();
757 continue;
758 }
759
760 /* Got good packet. Verify command is right. */
761 if (phdr.cmd != GDB_STATUS)
762 {
763 /* Wrong response. Resend command. */
764 send_query_cmd ();
765 continue;
766 }
767 /* Packet is fine. Exit loop. */
768 return inferior_pid;
769 }
770}
771
772/* Read the remote registers. */
773
774static void
775nrom_fetch_registers (regno)
776 int regno;
777{
778 char buf[NROM_BUF_SIZE];
779 char regs[REGISTER_BYTES];
780 int i;
781
782#ifdef DEBUG
783 printf_filtered ("reg no is %d\n",regno);
784#endif
785
786 nrom_send (GDB_READ_REGS, NULL, 0, -1, 0, buf);
787 memcpy (regs, buf, REGISTER_BYTES);
788 for (i = 0; i < NUM_REGS; i++)
789 supply_register (i, &regs[REGISTER_BYTE(i)]);
790#ifdef NO_SINGLE_REG
791 nrom_send (GDB_READ_REGS, NULL, 0, regno, 0, buf);
792 if (regno != -1)
793 supply_register(regno,buf);
794 else
795 {
796 memcpy (regs, buf, REGISTER_BYTES);
797 for (i = 0; i < NUM_REGS; i++)
798 supply_register (i, &regs[REGISTER_BYTE(i)]);
799 }
800#endif
801}
802
803static void
804nrom_send (cmd, data, datalen, addr, len, resp)
805 int cmd;
806 char *data;
807 int datalen;
808 long addr;
809 long len;
810 char *resp;
811{
812 GPKTHDR phdr;
813 char inbuf[NROM_BUF_SIZE];
814
815 while (1)
816 {
817 while (send_pkt (cmd, data, datalen, addr, len) < 0)
818 ;
819 if (read_pkt (inbuf) != -1)
820 {
821 if (parse_pkt (inbuf, &phdr, resp) < 0)
822 continue;
823 if (phdr.cmd != GDB_NACK)
824 return;
825 }
826 }
827}
828
829static void
830nrom_set_filetype (args, fromtty)
831 char *args;
832 int fromtty;
833{
834 if (args[0] == 'b')
835 nrom_filetype = BINARY_FTYPE;
836 else if (args[0] == 'm')
837 nrom_filetype = MOTO_SREC;
838 else if (args[0] == 'i')
839 nrom_filetype = INTEL_HEX;
840 else
841 printf_filtered ("Unknown file type\n");
842}
843
844static void
845nrom_set_ipaddr (args, fromtty)
846 char *args;
847 int fromtty;
848{
849 struct hostent *h;
850 char buf[10];
851 int i,j,val;
852 unsigned long newip = 0;
853
854 /* First do a check to see if they typed in a hostname. */
855 if (!(*args))
856 error ("Please enter a hostname or IP address");
857
858 h = gethostbyname (args);
859 if (h)
860 {
861 /* It is a hostname. We just need the ipaddress. */
862 memcpy (&nrom_ipaddr, h->h_addr, h->h_length);
863 }
864 else
865 {
866 /* Better be in decimal dot notation,ie. xx.xx.xx.xx */
867 if (isdigit (args[0]) && strchr (args, '.'))
868 {
869 j = 4;
870 while (j)
871 {
872 memset (buf, 0, 10);
873 i = 0;
874 while((*args) && (*args != '.'))
875 {
876 buf[i] = *args++;
877 i++;
878 }
879 if (i)
880 {
881 val = (int) strtol (buf, NULL, 10);
882
883 if (val > 255)
884 error ("Invalid IP address");
885
886 j--;
887 newip |= val << (8 * j);
888 args++;
889 }
890 }
891 }
892 else
893 {
894 error ("Invalid host name/address");
895 }
896 nrom_ipaddr = newip;
897 }
898}
899
900static void
901nrom_set_load_port (args, fromtty)
902 char *args;
903 int fromtty;
904{
905 load_port = (int) strtol (args, NULL, 10);
906}
907
908static void
909nrom_set_target_port (args, from_tty)
910 char *args;
911 int from_tty;
912{
913 target_port = (int) strtol (args, NULL, 10);
914}
915
916static void
917nrom_set_control_port (args, fromtty)
918 char *args;
919 int fromtty;
920{
921 control_port = (int) strtol (args, NULL, 10);
922}
923
924static void
925nrom_show_status (args,from_tty)
926 char *args;
927 int from_tty;
928{
929 unsigned char *i;
930
931 i = (unsigned char *)&nrom_ipaddr;
932
933 printf_filtered ("NetROM target port is %d\n", target_port);
934 printf_filtered ("NetROM download port is %d\n", load_port);
935 printf_filtered ("NetROM debug control port is %d\n", control_port);
936
937 printf_filtered ("NetROM IP Address is %d.%d.%d.%d\n",
938 UC(i[0]), UC(i[1]), UC(i[2]), UC(i[3]));
939 if (nrom_filetype == BINARY_FTYPE)
940 printf_filtered ("download filetype is binary\n");
941 else if (nrom_filetype == MOTO_SREC)
942 printf_filtered ("download filetype is moto-srec\n");
943 else if (nrom_filetype == INTEL_HEX)
944 printf_filtered ("download filetype is intel-hex\n");
945}
946
947/* Pass arguments directly to the NetROM. */
948
949static void
950nrom_passthru (args, fromtty)
951 char *args;
952 int fromtty;
953{
954 char buf[1024];
955
956 sprintf(buf, "%s\n", args);
957 if (nrom_control_send (buf, strlen (buf)) < 0)
958 error ("nrom_reset: control_send() of `%s'failed", args);
959}
960
961static void
962nrom_store_registers (regno)
963int regno;
964{
965 char buf[NROM_BUF_SIZE];
966 int i;
967 char *p;
968
969 p = buf;
970 for (i = 0; i < REGISTER_BYTES; i++)
971 {
972 *p++ = tohex ((registers[i] >> 4) & 0xf);
973 *p++ = tohex (registers[i] & 0xf);
974 }
975 *p = '\0';
976 nrom_send (GDB_WRITE_REGS, buf, REGISTER_BYTES * 2, 0, REGISTER_BYTES * 2,
977 buf);
978}
979
980static int
981nrom_xfer_inferior_memory (memaddr, myaddr, len, write, target)
982 CORE_ADDR memaddr;
983 char *myaddr;
984 int len;
985 int write;
986 struct target_ops *target;
987{
988 if (write)
989 return nrom_write_inferior_memory (memaddr, myaddr, len);
990 else
991 return nrom_read_inferior_memory (memaddr, myaddr, len);
992}
993
994/* Copy LEN bytes of data from debugger memory at MYADDR
995 to inferior's memory at MEMADDR. Returns errno value. */
996
997static int
998nrom_write_inferior_memory (memaddr, myaddr, len)
999 CORE_ADDR memaddr;
1000 char *myaddr;
1001 int len;
1002{
1003 char buf[NROM_BUF_SIZE],obuf[NROM_BUF_SIZE];
1004 int i;
1005 char *p;
1006
1007 p = obuf;
1008 for (i = 0; i < len; i++)
1009 {
1010 *p++ = tohex ((myaddr[i] >> 4) & 0xf);
1011 *p++ = tohex (myaddr[i] & 0xf);
1012 }
1013 *p = '\0';
1014 nrom_send (GDB_WRITE_MEM, obuf, len * 2, memaddr, len, buf);
1015
1016 return len;
1017}
1018
1019/* Read LEN bytes from inferior memory at MEMADDR. Put the result
1020 at debugger address MYADDR. Returns errno value. */
1021
1022static int
1023nrom_read_inferior_memory (memaddr, myaddr, len)
1024 CORE_ADDR memaddr;
1025 char *myaddr;
1026 int len;
1027{
1028 char buf[NROM_BUF_SIZE];
1029
1030 nrom_send (GDB_READ_MEM, NULL, 0, memaddr, len, buf);
1031 memcpy (myaddr, buf, len);
1032 return len;
1033}
1034
1035static void
1036nrom_files_info (ignore)
1037 struct target_ops *ignore;
1038{
1039}
1040
1041static void
1042nrom_mourn()
1043{
1044 unpush_target (&nrom_ops);
1045 generic_mourn_inferior ();
1046}
1047
1048/* Convert a packet into its parts and verify check sum. */
1049
1050static int
1051parse_pkt (pkt, hdr, data)
1052 unsigned char *pkt;
1053 GPKTHDR *hdr;
1054 char *data;
1055{
1056 unsigned char xcsum;
1057 unsigned char *dptr;
1058
1059 /* Build packet header from received data. */
1060 hex2mem (pkt, (char *) hdr, sizeof(GPKTHDR));
1061 if (remote_debug > 1)
1062 {
1063 printf_filtered ("Packet received: csum = %x,seq number = %x,len = %d\n",
1064 hdr->csum,hdr->seq_num,hdr->len);
1065 printf_filtered ("cmd = %x,addr = %x,datalen = %d\n",
1066 hdr->cmd,hdr->addr,hdr->datalen);
1067 }
1068 /* Skip first two bytes of packet when computing checksum. */
1069 dptr = (sizeof(GPKTHDR) * 2) + pkt;
1070 pkt += 2;
1071 if (remote_debug > 1)
1072 {
1073 printf_filtered ("Computing checksum over pkt %s\n",pkt);
1074 printf_filtered ("Of length %d\n",strlen(pkt));
1075 }
1076 xcsum = compute_csum (pkt, strlen (pkt));
1077 if (xcsum != hdr->csum)
1078 {
1079 if (remote_debug)
1080 printf_filtered ("Checksum failure: computed %x, received %x\n",xcsum,
1081 hdr->csum);
1082 return (-1);
1083 }
1084
1085 /* Copy data portion to callers data buffer converting from ASCII
1086 to data as we go. */
1087 hex2mem (dptr, data, hdr->datalen);
1088 return 0;
1089}
1090
1091static int
1092read_pkt (pkt)
1093 char *pkt;
1094{
1095 int n, tries;
1096 struct sockaddr_in from;
1097 int from_len = sizeof(from);
1098 int gotstart;
1099 int total_len;
1100 char *p;
1101
1102 p = pkt;
1103 total_len = 0;
1104 gotstart = 0;
1105
1106 while (1)
1107 {
1108 /* Don't let us get wedged if the target is losing. */
1109 QUIT;
1110
1111 if (bufdata == 0)
1112 {
1113 bufindex = 0;
1114 n = NROM_BUF_SIZE;
1115 /* Perform read on socket. This will wait. */
1116 bufdata = recvfrom (nrom_targ_sock, readbuf, n, 0, &from, &from_len);
1117 if (bufdata < 0)
1118 {
1119 printf_filtered ("Error on socket read of %d\n",errno);
1120 return (-1);
1121 }
1122 if (remote_debug > 2)
1123 {
1124 readbuf[bufdata] = '\0';
1125 printf_filtered ("Received %d bytes. Data is %s\n",
1126 bufdata, readbuf);
1127 }
1128 }
1129
1130 /* skip stuff between packets */
1131 while (gotstart == 0 && bufdata != 0
1132 && readbuf[bufindex] != GDB_START_DELIMITER)
1133 {
1134 bufdata--;
1135 bufindex++;
1136 }
1137
1138 /* look for a start if we haven't seen one */
1139 if (gotstart == 0 && bufdata != 0
1140 && readbuf[bufindex] == GDB_START_DELIMITER)
1141 {
1142 gotstart = 1;
1143 bufindex++;
1144 bufdata--;
1145 }
1146
1147 /* copy packet data */
1148 if (gotstart != 0)
1149 {
1150 while (bufdata && readbuf[bufindex] != GDB_END_DELIMITER)
1151 {
1152 *p = readbuf[bufindex];
1153 p++;
1154 bufdata--;
1155 bufindex++;
1156 total_len++;
1157 if (total_len > NROM_BUF_SIZE)
1158 {
1159 error ("read_pkt: packet length exceeds %d\n",
1160 NROM_BUF_SIZE);
1161 return (-1);
1162 }
1163 }
1164 *p = '\0';
1165 if (remote_debug > 2)
1166 printf_filtered ("Packet is '%s'\n", pkt);
1167 }
1168
1169 /* Make sure this is the end of the packet. */
1170 if (gotstart != 0 && bufdata != 0
1171 && readbuf[bufindex] == GDB_END_DELIMITER)
1172 {
1173 gotstart = 0;
1174 bufindex++;
1175 bufdata--;
1176 /* Ensure that the packet is terminated. */
1177 *p = '\0';
1178 if (remote_debug > 2)
1179 printf_filtered ("Returning '%s'\n", pkt);
1180 return 0;
1181 }
1182 }
1183}
1184
1185static void
1186send_query_cmd ()
1187{
1188 while (send_pkt (GDB_QUERY_CMD, NULL, 0, 0, 0) < 0)
1189 ;
1190}
1191
1192static int
1193send_pkt (cmd, data, datalen, addr, len)
1194 int cmd;
1195 char *data;
1196 int datalen;
1197 long addr;
1198 int len;
1199{
1200 char c[2];
1201 unsigned char seq;
1202 struct sockaddr_in mysin;
1203 int send_cnt;
1204
1205 while (1)
1206 {
1207 /* Get a sequence number for this packet. */
1208 seq = get_seq_number ();
1209 /* Build the packet. */
1210 build_pkt (cmd, data, datalen, workbuf, addr, len, seq);
1211 /* Put delimiters around the pkt. */
1212 memset (sendbuf, 0, NROM_BUF_SIZE);
1213 sendbuf[0] = GDB_START_DELIMITER;
1214 strcat (sendbuf, workbuf);
1215 c[0] = GDB_END_DELIMITER;
1216 c[1] = '\0';
1217 strcat (sendbuf, c);
1218
1219 /* Send the packet out on our socket. */
1220 if (remote_debug > 1)
1221 printf_filtered ("Sending pkt: %s\n", sendbuf);
1222 mysin.sin_family = AF_INET;
1223 mysin.sin_port = target_port;
1224 mysin.sin_addr.S_un.S_addr = nrom_ipaddr;
1225
1226 send_cnt = 0;
1227 while (send_cnt < MAX_SEND_ATTEMPTS)
1228 {
1229 if (sendto (nrom_targ_sock, sendbuf, strlen(sendbuf), 0, &mysin,
1230 sizeof(struct sockaddr_in)) < 0)
1231 {
1232 printf_filtered ("sendto error of %d\n", errno);
1233 send_cnt++;
1234 }
1235 else
1236 break;
1237 }
1238 if (send_cnt >= MAX_SEND_ATTEMPTS)
1239 {
1240 printf_filtered ("Socket send failed after %d tries\n",
1241 MAX_SEND_ATTEMPTS);
1242 return (-1);
1243 }
1244 return 1;
1245 }
1246}
1247
1248/* Convert number NIB to a hex digit. */
1249
1250static int
1251tohex (nib)
1252 int nib;
1253{
1254 if (nib < 10)
1255 return '0' + nib;
1256 else
1257 return 'a' + nib - 10;
1258}
1259
1260/* snatched from Stevens, pp279+ */
1261
1262int
1263writen (sock, ptr, nbytes)
1264 int sock;
1265 char *ptr;
1266 int nbytes;
1267{
1268 int nleft, nwritten;
1269 char *buf = ptr;
1270
1271 nleft = nbytes;
1272 while (nleft > 0)
1273 {
1274 nwritten = write (sock, buf, nleft);
1275 if (nwritten <= 0)
1276 return nwritten;
1277 nleft -= nwritten;
1278 buf += nwritten;
1279 }
1280 return (nbytes - nleft);
1281}
1282
1283/* Define the target vector. */
1284
1285struct target_ops nrom_ops = {
1286 "nrom", /* to_shortname */
1287 "Remote XDI `NetROM' target", /* to_longname */
1288 "Remote debug using a NetROM over Ethernet",
1289 nrom_open, /* to_open */
1290 nrom_close,
1291 nrom_attach,
1292 nrom_detach,
1293 nrom_resume,
1294 nrom_wait, /* to_wait */
1295 nrom_fetch_registers, /* to_fetch_registers */
1296 nrom_store_registers, /* to_store_registers */
1297 nrom_prepare_to_store, /* to_prepare_to_store */
1298 nrom_xfer_inferior_memory, /* to_xfer_memory */
1299 nrom_files_info, /* to_files_info */
1300 NULL, /* to_insert_breakpoint */
1301 NULL, /* to_remove_breakpoint */
1302 NULL,
1303 NULL,
1304 NULL,
1305 NULL,
1306 NULL,
1307 nrom_kill,
1308 nrom_load,
1309 NULL,
1310 nrom_create_inferior, /* to_create_inferior */
1311 nrom_mourn,
1312 nrom_can_run,
1313 0, /* to_notice_signals */
1314 0,
1315 process_stratum, /* to_stratum */
1316 NULL, /* to_next */
1317 1,
1318 1,
1319 1,
1320 1,
1321 0, /* to_has_execution */
1322 NULL, /* sections */
1323 NULL, /* sections_end */
1324 OPS_MAGIC /* to_magic */
1325};
1326
1327void
1328_initialize_remote_nrom ()
1329{
1330 add_target (&nrom_ops);
1331
1332 /* Add some commands for helpers. */
1333 add_cmd ("nrom_ipaddr", no_class, nrom_set_ipaddr,
1334 "Set the IP Address of the NetROM\n",
1335 &setlist);
1336 add_cmd ("target_port", no_class, nrom_set_target_port,
1337 "Set the Port to use for NetROM target communication\n",
1338 &setlist);
1339 add_cmd ("load_port", no_class, nrom_set_load_port,
1340 "Set the Port to use for NetROM downloads\n",
1341 &setlist);
1342 add_cmd ("control_port", no_class, nrom_set_control_port,
1343 "Set the Port to use for NetROM debugger services\n",
1344 &setlist);
1345 add_cmd ("nrom_filetype", no_class, nrom_set_filetype,
1346 "Set the filetype to use on NetROM downloads",
1347 &setlist);
1348
1349 add_cmd ("nrom", no_class, nrom_show_status,
1350 "Show the current NetROM status\n",
1351 &showlist);
1352
1353 add_cmd ("nrom", no_class, nrom_passthru,
1354 "Pass arguments as command to NetROM",
1355 &cmdlist);
1356}
This page took 0.098788 seconds and 4 git commands to generate.