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