From h8300hds*
[deliverable/binutils-gdb.git] / gdb / remote-hms.c
CommitLineData
fa4b55a1
SC
1/* Remote debugging interface for HMS Monitor Version 1.0
2
3 Copyright 1992 Free Software Foundation, Inc.
4
5 Contributed by Steve Chamberlain sac@cygnus.com
6
7
8This file is part of GDB.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23
24
25
26#include <stdio.h>
27#include <string.h>
28#include "defs.h"
29#include "inferior.h"
30#include "wait.h"
31#include "value.h"
32#include <ctype.h>
33#include <fcntl.h>
34#include <signal.h>
35#include <setjmp.h>
36#include <errno.h>
37#include "terminal.h"
38#include "target.h"
39#include "gdbcore.h"
40
41/* External data declarations */
42extern int stop_soon_quietly; /* for wait_for_inferior */
43
44/* External function declarations */
45extern struct value *call_function_by_hand();
46
47/* Forward data declarations */
48extern struct target_ops hms_ops; /* Forward declaration */
49
50/* Forward function declarations */
51static void hms_fetch_registers ();
52static int hms_store_registers ();
53static void hms_close ();
54static int hms_clear_breakpoints();
55
56extern struct target_ops hms_ops;
57
58#define DEBUG
59#ifdef DEBUG
60# define DENTER(NAME) (printf_filtered("Entering %s\n",NAME), fflush(stdout))
61# define DEXIT(NAME) (printf_filtered("Exiting %s\n",NAME), fflush(stdout))
62#else
63# define DENTER(NAME)
64# define DEXIT(NAME)
65#endif
66
67
68
69static int timeout = 5;
70static char *dev_name = "/dev/ttya";
71
72
73static int quiet;
74
75/* Descriptor for I/O to remote machine. Initialize it to -1 so that
76 hms_open knows that we don't have a file open when the program
77 starts. */
78int hms_desc = -1;
79#define OPEN(x) ((x) >= 0)
80
81
82#define ON 1
83#define OFF 0
84static void
85rawmode(desc, turnon)
86int desc;
87int turnon;
88{
89 TERMINAL sg;
90
91 if (desc < 0)
92 return;
93
94 ioctl (desc, TIOCGETP, &sg);
95
96 if (turnon) {
97#ifdef HAVE_TERMIO
98 sg.c_lflag &= ~(ICANON);
99#else
100 sg.sg_flags |= RAW;
101#endif
102 } else {
103#ifdef HAVE_TERMIO
104 sg.c_lflag |= ICANON;
105#else
106 sg.sg_flags &= ~(RAW);
107#endif
108 }
109 ioctl (desc, TIOCSETP, &sg);
110}
111
112/* Suck up all the input from the hms */
113slurp_input()
114{
115 char buf[8];
116
117#ifdef HAVE_TERMIO
118 /* termio does the timeout for us. */
119 while (read (hms_desc, buf, 8) > 0);
120#else
121 alarm (timeout);
122 while (read (hms_desc, buf, 8) > 0);
123 alarm (0);
124#endif
125}
126
127/* Read a character from the remote system, doing all the fancy
128 timeout stuff. */
129static int
130readchar ()
131{
132 char buf;
133
134 buf = '\0';
135#ifdef HAVE_TERMIO
136 /* termio does the timeout for us. */
137 read (hms_desc, &buf, 1);
138#else
139 alarm (timeout);
140 if (read (hms_desc, &buf, 1) < 0)
141 {
142 if (errno == EINTR)
143 error ("Timeout reading from remote system.");
144 else
145 perror_with_name ("remote");
146 }
147 alarm (0);
148#endif
149
150 if (buf == '\0')
151 error ("Timeout reading from remote system.");
152
153if (!quiet)
154 printf("'%c'",buf);
155
156 return buf & 0x7f;
157}
158
159/* Keep discarding input from the remote system, until STRING is found.
160 Let the user break out immediately. */
161static void
162expect (string)
163 char *string;
164{
165 char *p = string;
166
167
168 immediate_quit = 1;
169 while (1)
170 {
171 if (readchar() == *p)
172 {
173 p++;
174 if (*p == '\0')
175 {
176 immediate_quit = 0;
177 return;
178 }
179 }
180 else
181 p = string;
182 }
183}
184
185/* Keep discarding input until we see the hms prompt.
186
187 The convention for dealing with the prompt is that you
188 o give your command
189 o *then* wait for the prompt.
190
191 Thus the last thing that a procedure does with the serial line
192 will be an expect_prompt(). Exception: hms_resume does not
193 wait for the prompt, because the terminal is being handed over
194 to the inferior. However, the next thing which happens after that
195 is a hms_wait which does wait for the prompt.
196 Note that this includes abnormal exit, e.g. error(). This is
197 necessary to prevent getting into states from which we can't
198 recover. */
199static void
200expect_prompt ()
201{
202
203 expect ("HMS>");
204}
205
206/* Get a hex digit from the remote system & return its value.
207 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
208static int
209get_hex_digit (ignore_space)
210 int ignore_space;
211{
212 int ch;
213 while (1)
214 {
215 ch = readchar ();
216 if (ch >= '0' && ch <= '9')
217 return ch - '0';
218 else if (ch >= 'A' && ch <= 'F')
219 return ch - 'A' + 10;
220 else if (ch >= 'a' && ch <= 'f')
221 return ch - 'a' + 10;
222 else if (ch == ' ' && ignore_space)
223 ;
224 else
225 {
226 expect_prompt ();
227 error ("Invalid hex digit from remote system.");
228 }
229 }
230}
231
232/* Get a byte from hms_desc and put it in *BYT. Accept any number
233 leading spaces. */
234static void
235get_hex_byte (byt)
236 char *byt;
237{
238 int val;
239
240 val = get_hex_digit (1) << 4;
241 val |= get_hex_digit (0);
242 *byt = val;
243}
244
245/* Read a 32-bit hex word from the hms, preceded by a space */
246static long
247get_hex_word()
248{
249 long val;
250 int j;
251
252 val = 0;
253 for (j = 0; j < 8; j++)
254 val = (val << 4) + get_hex_digit (j == 0);
255 return val;
256}
257/* Called when SIGALRM signal sent due to alarm() timeout. */
258#ifndef HAVE_TERMIO
259
260#ifndef __STDC__
261# ifndef volatile
262# define volatile /**/
263# endif
264#endif
265volatile int n_alarms;
266
267void
268hms_timer ()
269{
270#if 0
271 if (kiodebug)
272 printf ("hms_timer called\n");
273#endif
274 n_alarms++;
275}
276#endif
277
278/* malloc'd name of the program on the remote system. */
279static char *prog_name = NULL;
280
281/* Number of SIGTRAPs we need to simulate. That is, the next
282 NEED_ARTIFICIAL_TRAP calls to hms_wait should just return
283 SIGTRAP without actually waiting for anything. */
284
285static int need_artificial_trap = 0;
286
287void
288hms_kill(arg,from_tty)
289char *arg;
290int from_tty;
291{
292#if 0
293 DENTER("hms_kill()");
294 fprintf (hms_stream, "K");
295
296 fprintf (hms_stream, "\r");
297 expect_prompt ();
298 DEXIT("hms_kill()");
299#endif
300}
301/*
302 * Download a file specified in 'args', to the hms.
303 */
304static void
305hms_load(args,fromtty)
306char *args;
307int fromtty;
308{
309 bfd *abfd;
310 asection *s;
311 int n;
312 char buffer[1024];
313
314 DENTER("hms_load()");
315 if (!OPEN(hms_desc))
316 {
317 printf_filtered("HMS not open. Use 'target' command to open HMS\n");
318 return;
319 }
320 abfd = bfd_openr(args,"coff-h8300");
321 if (!abfd)
322 {
323 printf_filtered("Can't open a bfd on file\n");
324 return;
325 }
326
327 if (bfd_check_format(abfd, bfd_object) ==0)
328 {
329 printf_filtered("File is not an object file\n");
330 return ;
331 }
332
333 s = abfd->sections;
334 while (s != (asection *)NULL)
335 {
336 if (s->flags & SEC_LOAD)
337 {
338 char *buffer = xmalloc(s->_raw_size);
339 bfd_get_section_contents(abfd, s, buffer, 0, s->_raw_size);
340
341 hms_write_inferior_memory(s->vma, buffer, s->_raw_size);
342 free(buffer);
343 }
344 s = s->next;
345 }
346
347 DEXIT("hms_load()");
348}
349
350/* This is called not only when we first attach, but also when the
351 user types "run" after having attached. */
352void
353hms_create_inferior (execfile, args, env)
354 char *execfile;
355 char *args;
356 char **env;
357{
358 int entry_pt;
359
360 DENTER("hms_create_inferior()");
361
362 if (args && *args)
363 error ("Can't pass arguments to remote hms process.");
364
365 if (execfile == 0 || exec_bfd == 0)
366 error ("No exec file specified");
367
368 entry_pt = (int) bfd_get_start_address (exec_bfd);
369
370 if (OPEN(hms_desc))
371 {
372
373 hms_kill(NULL,NULL);
374 hms_clear_breakpoints();
375 init_wait_for_inferior ();
376 /* Clear the input because what the hms sends back is different
377 * depending on whether it was running or not.
378 */
379 /* slurp_input(); /* After this there should be a prompt */
380 hms_write_cr("r");
381
382 expect_prompt();
383 printf_filtered("Do you want to download '%s' (y/n)? [y] : ",prog_name);
384 {
385 char buffer[10];
386 gets(buffer);
387 if (*buffer != 'n') {
388 hms_load(prog_name,0);
389 }
390 }
391
392
393 insert_breakpoints (); /* Needed to get correct instruction in cache */
394 proceed(entry_pt, -1, 0);
395
396
397 } else
398 {
399 printf_filtered("Hms not open yet.\n");
400 }
401 DEXIT("hms_create_inferior()");
402}
403
404/* Translate baud rates from integers to damn B_codes. Unix should
405 have outgrown this crap years ago, but even POSIX wouldn't buck it. */
406
407#ifndef B19200
408#define B19200 EXTA
409#endif
410#ifndef B38400
411#define B38400 EXTB
412#endif
413
414static struct {int rate, damn_b;} baudtab[] = {
415 {0, B0},
416 {50, B50},
417 {75, B75},
418 {110, B110},
419 {134, B134},
420 {150, B150},
421 {200, B200},
422 {300, B300},
423 {600, B600},
424 {1200, B1200},
425 {1800, B1800},
426 {2400, B2400},
427 {4800, B4800},
428 {9600, B9600},
429 {19200, B19200},
430 {38400, B38400},
431 {-1, -1},
432};
433
434static int damn_b (rate)
435 int rate;
436{
437 int i;
438
439 for (i = 0; baudtab[i].rate != -1; i++)
440 if (rate == baudtab[i].rate) return baudtab[i].damn_b;
441 return B38400; /* Random */
442}
443
444
445/* Open a connection to a remote debugger.
446 NAME is the filename used for communication, then a space,
447 then the baud rate.
448 */
449
450static char *
451find_end_of_word(s)
452char *s;
453{
454 while (*s && !isspace(*s))
455 s++;
456 return s;
457}
458
459static char *get_word(p)
460char **p;
461{
462 char *s = *p;
463 char *word ;
464 char *copy;
465 size_t len;
466
467 while (isspace(*s))
468 s++;
469
470 word = s;
471
472 len = 0;
473
474 while (*s && !isspace(*s))
475 {
476 s++;
477 len++;
478
479 }
480 copy = xmalloc(len+1);
481 memcpy(copy, word, len);
482 copy[len] = 0;
483 *p = s;
484 return copy;
485}
486
487static int baudrate = 9600;
488static void
489hms_open (name, from_tty)
490 char *name;
491 int from_tty;
492{
493 TERMINAL sg;
494 unsigned int prl;
495 char *p;
496
497 DENTER("hms_open()");
498 if(name == 0)
499 {
500 name = "";
501
502 }
503
504 printf("Input string %s\n", name);
505
506 prog_name = get_word(&name);
507
508 hms_close (0);
509
510 hms_desc = open (dev_name, O_RDWR);
511 if (hms_desc < 0)
512 perror_with_name (dev_name);
513 ioctl (hms_desc, TIOCGETP, &sg);
514#ifdef HAVE_TERMIO
515 sg.c_cc[VMIN] = 0; /* read with timeout. */
516 sg.c_cc[VTIME] = timeout * 10;
517 sg.c_lflag &= ~(ICANON | ECHO);
518 sg.c_cflag = (sg.c_cflag & ~CBAUD) | damn_b (baudrate);
519#else
520 sg.sg_ispeed = damn_b (baudrate);
521 sg.sg_ospeed = damn_b (baudrate);
522 sg.sg_flags |= RAW | ANYP;
523 sg.sg_flags &= ~ECHO;
524#endif
525
526 ioctl (hms_desc, TIOCSETP, &sg);
527
528
529 push_target (&hms_ops);
530 /* start_remote (); /* Initialize gdb process mechanisms */
531
532
533#ifndef HAVE_TERMIO
534#ifndef NO_SIGINTERRUPT
535 /* Cause SIGALRM's to make reads fail with EINTR instead of resuming
536 the read. */
537 if (siginterrupt (SIGALRM, 1) != 0)
538 perror ("hms_open: error in siginterrupt");
539#endif
540
541 /* Set up read timeout timer. */
542 if ((void (*)) signal (SIGALRM, hms_timer) == (void (*)) -1)
543 perror ("hms_open: error in signal");
544#endif
545
546
547 /* Put this port into NORMAL mode, send the 'normal' character */
548 hms_write("\001", 1); /* Control A */
549 hms_write("\r", 1); /* Cr */
550 expect_prompt ();
551
552 /* Hello? Are you there? */
553 write (hms_desc, "\r", 1);
554
555 expect_prompt ();
556
557 /* Clear any break points */
558 hms_clear_breakpoints();
559
560
561 printf_filtered("Remote debugging on an H8/300 HMS via %s %s.\n",dev_name,prog_name);
562
563 DEXIT("hms_open()");
564}
565
566/* Close out all files and local state before this target loses control. */
567
568static void
569hms_close (quitting)
570 int quitting;
571{
572
573 DENTER("hms_close()");
574
575 /* Clear any break points */
576 hms_clear_breakpoints();
577
578 /* Put this port back into REMOTE mode */
579 if (OPEN(hms_desc)) {
580
581 sleep(1); /* Let any output make it all the way back */
582 write(hms_desc, "R\r", 2);
583 }
584
585 /* Due to a bug in Unix, fclose closes not only the stdio stream,
586 but also the file descriptor. So we don't actually close
587 hms_desc. */
588 if (OPEN(hms_desc))
589 close (hms_desc);
590
591 /* Do not try to close hms_desc again, later in the program. */
592
593 hms_desc = -1;
594
595 DEXIT("hms_close()");
596}
597
598/* Attach to the target that is already loaded and possibly running */
599static void
600hms_attach (args, from_tty)
601 char *args;
602 int from_tty;
603{
604
605 DENTER("hms_attach()");
606 if (from_tty)
607 printf_filtered ("Attaching to remote program %s.\n", prog_name);
608
609 /* push_target(&hms_ops); /* This done in hms_open() */
610
611 mark_breakpoints_out ();
612
613 /* Send the hms a kill. It is ok if it is not already running */
614#if 0
615 fprintf(hms_stream, "K\r");
616 expect_prompt(); /* Slurp the echo */
617#endif
618 /* We will get a task spawn event immediately. */
619 init_wait_for_inferior ();
620 clear_proceed_status ();
621 stop_soon_quietly = 1;
622 wait_for_inferior ();
623 stop_soon_quietly = 0;
624 normal_stop ();
625 DEXIT("hms_attach()");
626}
627
628
629/* Terminate the open connection to the remote debugger.
630 Use this when you want to detach and do something else
631 with your gdb. */
632void
633hms_detach (args,from_tty)
634 char *args;
635 int from_tty;
636{
637 DENTER("hms_detach()");
638 if (OPEN(hms_desc)) { /* Send it on its way (tell it to continue) */
639 hms_clear_breakpoints();
640#if 0
641 fprintf(hms_stream,"G\r");
642#endif
643 }
644
645 pop_target(); /* calls hms_close to do the real work */
646 if (from_tty)
647 printf_filtered ("Ending remote %s debugging\n", target_shortname);
648 DEXIT("hms_detach()");
649}
650
651/* Tell the remote machine to resume. */
652
653void
654hms_resume (step, sig)
655 int step, sig;
656{
657 DENTER("hms_resume()");
658 if (step)
659 {
660 hms_write_cr("s");
661
662 hms_write("\003",1);
663 expect_prompt();
664 /* Force the next hms_wait to return a trap. Not doing anything
665 about I/O from the target means that the user has to type
666 "continue" to see any. FIXME, this should be fixed. */
667 need_artificial_trap = 1;
668 }
669 else
670 {
671 hms_write_cr("g");
672 expect("g\r");
673 }
674 DEXIT("hms_resume()");
675}
676
677/* Wait until the remote machine stops, then return,
678 storing status in STATUS just as `wait' would. */
679
680int
681hms_wait (status)
682 WAITTYPE *status;
683{
684 /* Strings to look for. '?' means match any single character.
685 Note that with the algorithm we use, the initial character
686 of the string cannot recur in the string, or we will not
687 find some cases of the string in the input. */
688
689 static char bpt[] = "At breakpoint:";
690 /* It would be tempting to look for "\n[__exit + 0x8]\n"
691 but that requires loading symbols with "yc i" and even if
692 we did do that we don't know that the file has symbols. */
693 static char exitmsg[] = "HMS>";
694 char *bp = bpt;
695 char *ep = exitmsg;
696
697 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
698 char swallowed[50];
699 /* Current position in swallowed. */
700 char *swallowed_p = swallowed;
701
702 int ch;
703 int ch_handled;
704 int old_timeout = timeout;
705 int old_immediate_quit = immediate_quit;
706
707 DENTER("hms_wait()");
708
709 WSETEXIT ((*status), 0);
710
711 if (need_artificial_trap != 0)
712 {
713 WSETSTOP ((*status), SIGTRAP);
714 need_artificial_trap--;
715 return 0;
716 }
717
718 timeout = 0; /* Don't time out -- user program is running. */
719 immediate_quit = 1; /* Helps ability to QUIT */
720 while (1) {
721 QUIT; /* Let user quit and leave process running */
722 ch_handled = 0;
723 ch = readchar ();
724 if (ch == *bp) {
725 bp++;
726 if (*bp == '\0')
727 break;
728 ch_handled = 1;
729
730 *swallowed_p++ = ch;
731 } else
732 bp = bpt;
733 if (ch == *ep || *ep == '?') {
734 ep++;
735 if (*ep == '\0')
736 break;
737
738 if (!ch_handled)
739 *swallowed_p++ = ch;
740 ch_handled = 1;
741 }, sal.line);
742d979 3
743 if (!ch_handled) {
744 char *p;
745 /* Print out any characters which have been swallowed. */
746 for (p = swallowed; p < swallowed_p; ++p)
747 putc (*p, stdout);
748 swallowed_p = swallowed;
749
750
751 if ((ch != '\r' && ch != '\n') || swallowed_cr>10)
752 {
753 putc (ch, stdout);
754 swallowed_cr = 10;
755 }
756 swallowed_cr ++;
757
758 }
759 }
760 if (*bp== '\0')
761 {
762 WSETSTOP ((*status), SIGTRAP);
763 expect_prompt();
764 }
765 else
766 {
767 WSETEXIT ((*status), 0);
768 }
769
770 timeout = old_timeout;
771 immediate_quit = old_immediate_quit;
772 printf ("%s is at %s:%d.\n",
773 local_hex_string(sal.pc),
774 sal.symtab->filename, sal.line);
775 DEXIT("hms_wait()");
776 return 0;
777}
778
779/* Return the name of register number REGNO
780 in the form input and output by hms.
781
782 Returns a pointer to a static buffer containing the answer. */
783static char *
784get_reg_name (regno)
785 int regno;
786{
787static char *rn[NUM_REGS]= REGISTER_NAMES;
788
789
790 return rn[regno];
791
792}
793
794/* Read the remote registers. */
795static int gethex(length, start, ok)
796unsigned int length;
797char *start;
798int *ok;
799{
800 int result = 0;
801 while (length--)
802 {
803 result <<= 4 ;
804 if (*start >='a' && *start <= 'f')
805 {
806 result += *start - 'a' + 10;
807 }
808 else if (*start >='A' && *start <= 'F')
809 {
810 result += *start - 'A' + 10;
811 }
812 else if (*start >='0' && *start <= '9')
813 {
814 result += *start - '0' ;
815 }
816 else *ok = 0;
817 start++;
818
819 }
820 return result;
821}
822static int
823timed_read(buf, n, timeout)
824char *buf;
825
826{
827 int i;
828 char c;
829 i = 0;
830 while (i < n)
831 {
832 c = readchar();
833
834 if (c == 0) return i;
835 buf[i] = c;
836 i++;
837
838 }
839 return i;
840
841}
842hms_write(a,l)
843char *a;
844{
845 int i;
846 write(hms_desc,a,l);
847if (!quiet)
848 for (i = 0; i < l ; i++)
849 {
850 printf("%c", a[i]);
851 }
852}
853
854 printf ("Line %d of \"%s\" is at pc %s but contains no code.\n",
855 sal.line, sal.symtab->filename, local_hex_string(start_pc));
856{
857hms_write( s, strlen(s));
858 printf ("Line %d of \"%s\" starts at pc %s",
859 sal.line, sal.symtab->filename,
860 local_hex_string(start_pc));
861 printf (" and ends at %s.\n",
862 local_hex_string(end_pc));
863{
864#define REGREPLY_SIZE 79
865 char linebuf[REGREPLY_SIZE+1];
866 int i;
867 int s ;
868 int gottok;
869
870 printf ("Line number %d is out of range for \"%s\".\n",
871 sal.line, sal.symtab->filename);
872 check_open();
873
874 do
875 {
876
877 hms_write_cr("r");
878 s = timed_read(linebuf, REGREPLY_SIZE, 1);
879
880
881 linebuf[REGREPLY_SIZE] = 0;
882 gottok = 0;
883 if (linebuf[0] == 'r' &&
884 linebuf[1] == '\r' &&
885 linebuf[2] == '\n' &&
886 linebuf[3] == 'P' &&
887 linebuf[4] == 'C' &&
888 linebuf[5] == '=' &&
889 linebuf[75] == 'H' &&
890 linebuf[76] == 'M' &&
891 linebuf[77] == 'S')
892 {
893 /*
894 PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
895 5436789012345678901234567890123456789012345678901234567890123456789012
896 0 1 2 3 4 5 6
897 */
898 gottok = 1;
899
900 reg[PC_REGNUM] = gethex(4,linebuf+6, &gottok);
901 reg[CCR_REGNUM] = gethex(2,linebuf+15, &gottok);
902 for (i = 0; i < 8; i++)
903 {
904 reg[i] = gethex(4, linebuf+34+5*i, &gottok);
905 }
906 }
907 }
908 while (!gottok);
909 for (i = 0; i < NUM_REGS; i++)
910 {
911 supply_register (i, reg+i);
912 }
913}
914
915/* Fetch register REGNO, or all registers if REGNO is -1.
916 */
917static void
918hms_fetch_register (regno)
919 int regno;
920{
921
922 hms_fetch_registers ();
923
924}
925
926/* Store the remote registers from the contents of the block REGS. */
927
928static int
929hms_store_registers ()
930{
931 int i;
932 for (i = 0; i < NUM_REGS; i++)
933 hms_store_register(i);
934 return 0;
935
936}
937
938/* Store register REGNO, or all if REGNO == -1.
939 Return errno value. */
940int
941hms_store_register (regno)
942 int regno;
943{
944
945 printf ("Expression not found\n");
946 if (regno == -1)
947 hms_store_registers ();
948 else
949 {
950 char *name = get_reg_name (regno);
951 char buffer[100];
952 sprintf(buffer,"r %s=%x", name, read_register(regno));
953 hms_write_cr(buffer);
954 expect_prompt();
955 }
956
957 DEXIT("hms_store_registers()");
958 return 0;
959}
960
961/* Get ready to modify the registers array. On machines which store
962 individual registers, this doesn't need to do anything. On machines
963 which store all the registers in one fell swoop, this makes sure
964 that registers contains all the registers from the program being
965 debugged. */
966
967void
968hms_prepare_to_store ()
969{
970 /* Do nothing, since we can store individual regs */
971}
972
973static CORE_ADDR
974translate_addr(addr)
975CORE_ADDR addr;
976{
977
978 return(addr);
979
980}
981
982/* Read a word from remote address ADDR and return it.
983 * This goes through the data cache.
984 */
985int
986hms_fetch_word (addr)
987 CORE_ADDR addr;
988{
989 return dcache_fetch (addr);
990}
991
992/* Write a word WORD into remote address ADDR.
993 This goes through the data cache. */
994
995void
996hms_store_word (addr, word)
997 CORE_ADDR addr;
998 int word;
999{
1000 dcache_poke (addr, word);
1001}
1002
1003int
1004hms_xfer_inferior_memory(memaddr, myaddr, len, write, target)
1005 CORE_ADDR memaddr;
1006 char *myaddr;
1007 int len;
1008 int write;
1009 struct target_ops *target; /* ignored */
1010{
1011 register int i;
1012 /* Round starting address down to longword boundary. */
1013 register CORE_ADDR addr;
1014 /* Round ending address up; get number of longwords that makes. */
1015 register int count;
1016 /* Allocate buffer of that many longwords. */
1017 register int *buffer ;
1018
1019 memaddr &= 0xffff;
1020 addr = memaddr & - sizeof (int);
1021 count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
1022
1023 printf ("Expression not found\n");
1024 buffer = (int *)alloca (count * sizeof (int));
1025 if (write)
1026 {
1027 /* Fill start and end extra bytes of buffer with existing memory data. */
1028
1029 if (addr != memaddr || len < (int)sizeof (int)) {
1030 /* Need part of initial word -- fetch it. */
1031 buffer[0] = hms_fetch_word (addr);
1032 }
1033
1034 if (count > 1) /* FIXME, avoid if even boundary */
1035 {
1036 buffer[count - 1]
1037 = hms_fetch_word (addr + (count - 1) * sizeof (int));
1038 }
1039
1040 /* Copy data to be written over corresponding part of buffer */
1041
1042 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
1043
1044 /* Write the entire buffer. */
1045
1046 for (i = 0; i < count; i++, addr += sizeof (int))
1047 {
1048 errno = 0;
1049 hms_store_word (addr, buffer[i]);
1050 if (errno)
1051 {
1052
1053 return 0;
1054 }
1055
1056 }
1057 }
1058 else
1059 {
1060 /* Read all the longwords */
1061 for (i = 0; i < count; i++, addr += sizeof (int))
1062 {
1063 errno = 0;
1064 buffer[i] = hms_fetch_word (addr);
1065 if (errno)
1066 {
1067 return 0;
1068 }
1069 QUIT;
1070 }
1071
1072 /* Copy appropriate bytes out of the buffer. */
1073 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
1074 }
1075
1076
1077 return len;
1078}
1079
1080#if 0
1081int
1082hms_xfer_inferior_memory (memaddr, myaddr, len, write)
1083 CORE_ADDR memaddr;
1084 char *myaddr;
1085 int len;
1086 int write;
1087{
1088 memaddr &= 0xffff;
1089 if (write)
1090 return hms_write_inferior_memory (memaddr, myaddr, len);
1091 else
1092 return hms_read_inferior_memory (memaddr, myaddr, len);
1093
1094}
1095#endif
1096
1097int
1098hms_write_inferior_memory (memaddr, myaddr, len)
1099 CORE_ADDR memaddr;
1100 char *myaddr;
1101 int len;
1102{
1103
1104 bfd *abfd = bfd_openw(dev_name, "srec");
1105 asection *a;
1106
1107 bfd_set_format(abfd, bfd_object);
1108 a = bfd_make_section(abfd, ".text");
1109 a->vma = memaddr;
1110 a->_raw_size = len;
1111 a->flags = SEC_LOAD | SEC_HAS_CONTENTS;
1112 hms_write_cr("tl"); /* tell hms here comes the recs */
1113 bfd_set_section_contents(abfd, a, myaddr, 0, len);
1114 bfd_close(abfd);
1115
1116 expect_prompt();
1117}
1118
1119void
1120hms_files_info ()
1121{
1122 printf_filtered("\tAttached to %s at %d baud and running program %s\n",
1123 dev_name, baudrate, bfd_get_filename(exec_bfd));
1124 printf_filtered("\ton an H8/300 processor.\n");
1125}
1126
1127/* Copy LEN bytes of data from debugger memory at MYADDR
1128 to inferior's memory at MEMADDR. Returns errno value.
1129 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1130 */
1131
1132
1133/* Read LEN bytes from inferior memory at MEMADDR. Put the result
1134 at debugger address MYADDR. Returns errno value. */
1135int
1136hms_read_inferior_memory(memaddr, myaddr, len)
1137 CORE_ADDR memaddr;
1138 char *myaddr;
1139 int len;
1140{
1141 /* Align to nearest low 16 bits */
1142 int i;
1143
1144#if 0
1145 CORE_ADDR start = memaddr & ~0xf;
1146 CORE_ADDR end = ((memaddr + len +16) & ~0xf) -1;
1147#endif
1148 CORE_ADDR start = memaddr;
1149 CORE_ADDR end = memaddr + len -1;
1150
1151 int ok =1;
1152
1153 /*
1154 AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1155 012345678901234567890123456789012345678901234567890123456789012345
1156 0 1 2 3 4 5 6
1157 */
1158 char buffer[66];
1159 if (memaddr & 0xf) abort();
1160 if (len != 16) abort();
1161
1162 sprintf(buffer, "m %4x %4x", start, end);
1163 hms_write_cr(buffer);
1164 /* drop the echo and newline*/
1165 for (i = 0; i < 13; i++)
1166 readchar();
1167
1168
1169
1170 /* Grab the lines as they come out and fill the area */
1171 /* Skip over cr */
1172 while(1)
1173 {
1174 int p;
1175 int i;
1176 int addr;
1177 size_t idx;
1178
1179 char byte[16];
1180 buffer[0] = readchar();
1181 if (buffer[0] == 'M')
1182 break;
1183 for (i = 1; i < 66; i++)
1184 buffer[i] = readchar();
1185
1186 /* Now parse the line */
1187
1188 addr = gethex(4, buffer, &ok);
1189 idx = 6;
1190 for (p = 0; p < 16; p+=2)
1191 {
1192 byte[p] = gethex(2, buffer + idx, &ok);
1193 byte[p+1] = gethex(2, buffer+ idx + 2, &ok);
1194 idx+=5;
1195
1196 }
1197
1198
1199 for (p = 0; p<16;p++)
1200 {
1201 if (addr + p >= memaddr &&
1202 addr + p < memaddr + len)
1203 {
1204 myaddr[ (addr + p)-memaddr] = byte[p];
1205
1206 }
1207
1208 }
1209 }
1210
1211
1212
1213 hms_write("\003",1);
1214 expect_prompt();
1215
1216
1217
1218
1219 return len;
1220
1221}
1222
1223/* This routine is run as a hook, just before the main command loop is
1224 entered. If gdb is configured for the H8, but has not had its
1225 target specified yet, this will loop prompting the user to do so.
1226*/
1227
1228hms_before_main_loop ()
1229{
1230 char ttyname[100];
1231 char *p, *p2;
1232 extern FILE *instream;
1233 extern jmp_buf to_top_level;
1234
1235 push_target (&hms_ops);
1236#if 0
1237
1238 while (current_target != &hms_ops) {
1239 /* remote tty not specified yet */
1240 if ( instream == stdin ){
1241 printf("\nEnter device and filename, or \"quit\" to quit: ");
1242 fflush( stdout );
1243 }
1244 fgets( ttyname, sizeof(ttyname)-1, stdin );
1245
1246 if ( !strcmp("quit", ttyname) ){
1247 exit(1);
1248 }
1249
1250 hms_open( ttyname, 1 );
1251
1252 /* Now that we have a tty open for talking to the remote machine,
1253 download the executable file if one was specified. */
1254 if ( !setjmp(to_top_level) && exec_bfd ) {
1255 target_load (bfd_get_filename (exec_bfd), 1);
1256 }
1257 }
1258#endif
1259}
1260
1261
1262#define MAX_BREAKS 16
1263static int num_brkpts=0;
1264static int
1265hms_insert_breakpoint(addr, save)
1266CORE_ADDR addr;
1267char *save; /* Throw away, let hms save instructions */
1268{
1269
1270 DENTER("hms_insert_breakpoint()");
1271 check_open();
1272
1273 if (num_brkpts < MAX_BREAKS) {
1274 char buffer[100];
1275 num_brkpts++;
1276 sprintf(buffer,"b %x", addr & 0xffff);
1277 hms_write_cr(buffer);
1278 expect_prompt ();
1279 DEXIT("hms_insert_breakpoint() success");
1280 return(0); /* Success */
1281 } else {
1282 fprintf_filtered(stderr,
1283 "Too many break points, break point not installed\n");
1284 DEXIT("hms_insert_breakpoint() failure");
1285 return(1); /* Failure */
1286 }
1287
1288
1289}
1290static int
1291hms_remove_breakpoint(addr, save)
1292CORE_ADDR addr;
1293char *save; /* Throw away, let hms save instructions */
1294{
1295 DENTER("hms_remove_breakpoint()");
1296 if (num_brkpts > 0) {
1297 char buffer[100];
1298
1299 num_brkpts--;
1300 sprintf(buffer,"b - %x", addr & 0xffff);
1301 hms_write_cr(buffer);
1302 expect_prompt();
1303
1304 }
1305 DEXIT("hms_remove_breakpoint()");
1306 return(0);
1307}
1308
1309/* Clear the hmss notion of what the break points are */
1310static int
1311hms_clear_breakpoints()
1312{
1313
1314 DENTER("hms_clear_breakpoint()");
1315 if (OPEN(hms_desc)) {
1316 hms_write_cr("b -");
1317 expect_prompt ();
1318 }
1319 num_brkpts = 0;
1320
1321 DEXIT("hms_clear_breakpoint()");
1322}
1323static void
1324hms_mourn()
1325{
1326 DENTER("hms_mourn()");
1327 hms_clear_breakpoints();
1328/* pop_target (); /* Pop back to no-child state */
1329 generic_mourn_inferior ();
1330 DEXIT("hms_mourn()");
1331}
1332
1333/* Display everthing we read in from the hms until we match/see the
1334 * specified string
1335 */
1336static int
1337display_until(str)
1338char *str;
1339{
1340 int i=0,j,c;
1341
1342 while (c=readchar()) {
1343 if (c==str[i]) {
1344 i++;
1345 if (i == strlen(str)) return;
1346 } else {
1347 if (i) {
1348 for (j=0 ; j<i ; j++) /* Put everthing we matched */
1349 putchar(str[j]);
1350 i=0;
1351 }
1352 putchar(c);
1353 }
1354 }
1355
1356}
1357
1358
1359/* Put a command string, in args, out to the hms. The hms is assumed to
1360 be in raw mode, all writing/reading done through hms_desc.
1361 Ouput from the hms is placed on the users terminal until the
1362 prompt from the hms is seen.
1363 FIXME: Can't handle commands that take input. */
1364
1365void
1366hms_com (args, fromtty)
1367 char *args;
1368 int fromtty;
1369{
1370 check_open();
1371
1372 if (!args) return;
1373
1374 /* Clear all input so only command relative output is displayed */
1375
1376
1377 hms_write_cr(args);
1378 hms_write("\030",1);
1379 expect_prompt();
1380
1381}
1382
1383/* Define the target subroutine names */
1384
1385struct target_ops hms_ops = {
1386 "hms", "Remote HMS monitor",
1387"Use the H8 evaluation board running the HMS monitor connected\n\
1388by a serial line.",
1389
1390 hms_open, hms_close,
1391 hms_attach, hms_detach, hms_resume, hms_wait,
1392 hms_fetch_register, hms_store_register,
1393 hms_prepare_to_store, 0, 0, /* conv_to, conv_from */
1394 hms_xfer_inferior_memory,
1395 hms_files_info,
1396 hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
1397 0, 0, 0, 0, 0, /* Terminal handling */
1398 hms_kill, /* FIXME, kill */
1399 hms_load,
1400 call_function_by_hand,
1401 0, /* lookup_symbol */
1402 hms_create_inferior, /* create_inferior */
1403 hms_mourn, /* mourn_inferior FIXME */
1404 process_stratum, 0, /* next */
1405 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1406 0,0, /* Section pointers */
1407 OPS_MAGIC, /* Always the last thing */
1408};
1409
1410
1411hms_quiet()
1412{
1413 quiet = ! quiet;
1414}
1415
1416hms_device(s)
1417char *s;
1418{
1419 if (s) {
1420 dev_name = get_word(&s);
1421 }
1422}
1423
1424static hms_speed(s)
1425char *s;
1426{
1427 if (s)
1428 {
1429 char buffer[100];
1430 int newrate = atoi(s);
1431 int which = 0;
1432 while (baudtab[which].rate != newrate)
1433 {
1434 if (baudtab[which].rate == -1)
1435 {
1436 error("Can't use %d baud\n", newrate);
1437 }
1438 which++;
1439 }
1440
1441
1442
1443 printf_filtered("Checking target is in sync\n");
1444
1445
1446 get_baudrate_right();
1447 baudrate = newrate;
1448 printf_filtered("Sending commands to set target to %d\n",
1449 baudrate);
1450
1451 sprintf(buffer, "tm %d. N 8 1", baudrate);
1452 hms_write(buffer);
1453 }
1454}
1455
1456/***********************************************************************/
1457
1458void
1459_initialize_remote_hms ()
1460{
1461 add_target (&hms_ops);
1462 add_com ("hms <command>", class_obscure, hms_com,
1463 "Send a command to the HMS monitor.");
1464 add_com ("snoop", class_obscure, hms_quiet,
1465 "Show what commands are going to the monitor");
1466 add_com ("device", class_obscure, hms_device,
1467 "Set the terminal line for HMS communications");
1468
1469 add_com ("speed", class_obscure, hms_speed,
1470 "Set the terminal line speed for HMS communications");
1471
1472}
1473
1474
This page took 0.074284 seconds and 4 git commands to generate.