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