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