]> Git Repo - binutils.git/blob - gdb/remote-hms.c
* target.h: Put remote_debug declaration back here. Add baud_rate.
[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 #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, gnutarget);
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 (pid, status)
668      int pid;
669      WAITTYPE *status;
670 {
671   /* Strings to look for.  '?' means match any single character.
672      Note that with the algorithm we use, the initial character
673      of the string cannot recur in the string, or we will not
674      find some cases of the string in the input.  */
675
676   static char bpt[] = "At breakpoint:";
677
678   /* It would be tempting to look for "\n[__exit + 0x8]\n"
679      but that requires loading symbols with "yc i" and even if
680      we did do that we don't know that the file has symbols.  */
681   static char exitmsg[] = "HMS>";
682   char *bp = bpt;
683   char *ep = exitmsg;
684
685   /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars.  */
686   char swallowed[50];
687
688   /* Current position in swallowed.  */
689   char *swallowed_p = swallowed;
690
691   int ch;
692   int ch_handled;
693   int old_timeout = timeout;
694   int old_immediate_quit = immediate_quit;
695   int swallowed_cr = 0;
696
697   WSETEXIT ((*status), 0);
698
699   if (need_artificial_trap != 0)
700     {
701       WSETSTOP ((*status), SIGTRAP);
702       need_artificial_trap--;
703       return 0;
704     }
705
706   timeout = -1;         /* Don't time out -- user program is running. */
707   immediate_quit = 1;           /* Helps ability to QUIT */
708   while (1)
709     {
710       QUIT;                     /* Let user quit and leave process running */
711       ch_handled = 0;
712       ch = readchar ();
713       if (ch == *bp)
714         {
715           bp++;
716           if (*bp == '\0')
717             break;
718           ch_handled = 1;
719
720           *swallowed_p++ = ch;
721         }
722       else
723         {
724           bp = bpt;
725         }
726       if (ch == *ep || *ep == '?')
727         {
728           ep++;
729           if (*ep == '\0')
730             break;
731
732           if (!ch_handled)
733             *swallowed_p++ = ch;
734           ch_handled = 1;
735         }
736       else
737         {
738           ep = exitmsg;
739         }
740
741       if (!ch_handled)
742         {
743           char *p;
744
745           /* Print out any characters which have been swallowed.  */
746           for (p = swallowed; p < swallowed_p; ++p)
747             putc (*p, stdout);
748           swallowed_p = swallowed;
749
750           if ((ch != '\r' && ch != '\n') || swallowed_cr > 10)
751             {
752               putc (ch, stdout);
753               swallowed_cr = 10;
754             }
755           swallowed_cr++;
756
757         }
758     }
759   if (*bp == '\0')
760     {
761       WSETSTOP ((*status), SIGTRAP);
762       expect_prompt ();
763     }
764   else
765     {
766       WSETEXIT ((*status), 0);
767     }
768
769   timeout = old_timeout;
770   immediate_quit = old_immediate_quit;
771   return 0;
772 }
773
774 /* Return the name of register number REGNO
775    in the form input and output by hms.
776
777    Returns a pointer to a static buffer containing the answer.  */
778 static char *
779 get_reg_name (regno)
780      int regno;
781 {
782   static char *rn[] = REGISTER_NAMES;
783
784   return rn[regno];
785 }
786
787 /* Read the remote registers.  */
788 static int
789 gethex (length, start, ok)
790      unsigned int length;
791      char *start;
792      int *ok;
793 {
794   int result = 0;
795
796   while (length--)
797     {
798       result <<= 4;
799       if (*start >= 'a' && *start <= 'f')
800         {
801           result += *start - 'a' + 10;
802         }
803       else if (*start >= 'A' && *start <= 'F')
804         {
805           result += *start - 'A' + 10;
806         }
807       else if (*start >= '0' && *start <= '9')
808         {
809           result += *start - '0';
810         }
811       else
812         *ok = 0;
813       start++;
814
815     }
816   return result;
817 }
818 static int
819 timed_read (buf, n, timeout)
820      char *buf;
821
822 {
823   int i;
824   char c;
825
826   i = 0;
827   while (i < n)
828     {
829       c = readchar ();
830
831       if (c == 0)
832         return i;
833       buf[i] = c;
834       i++;
835
836     }
837   return i;
838 }
839
840 hms_write (a, l)
841      char *a;
842 {
843   int i;
844
845   SERIAL_WRITE (desc, a, l);
846
847   if (!quiet)
848     for (i = 0; i < l; i++)
849       {
850         printf ("%c", a[i]);
851       }
852 }
853
854 hms_write_cr (s)
855      char *s;
856 {
857   hms_write (s, strlen (s));
858   hms_write ("\r", 1);
859 }
860
861 static void
862 hms_fetch_register (dummy)
863      int dummy;
864 {
865 #define REGREPLY_SIZE 79
866   char linebuf[REGREPLY_SIZE + 1];
867   int i;
868   int s;
869   int gottok;
870
871   REGISTER_TYPE reg[NUM_REGS];
872   int foo[8];
873
874   check_open ();
875
876   do
877     {
878
879       hms_write_cr ("r");
880       s = timed_read (linebuf, REGREPLY_SIZE, 1);
881
882       linebuf[REGREPLY_SIZE] = 0;
883       gottok = 0;
884       if (linebuf[0] == 'r' &&
885           linebuf[3] == 'P' &&
886           linebuf[4] == 'C' &&
887           linebuf[5] == '=' &&
888           linebuf[75] == 'H' &&
889           linebuf[76] == 'M' &&
890           linebuf[77] == 'S')
891         {
892           /*
893         PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
894         5436789012345678901234567890123456789012345678901234567890123456789012
895         0      1         2         3         4         5         6
896         */
897           gottok = 1;
898
899           reg[PC_REGNUM] = gethex (4, linebuf + 6, &gottok);
900           reg[CCR_REGNUM] = gethex (2, linebuf + 15, &gottok);
901           for (i = 0; i < 8; i++)
902             {
903               reg[i] = gethex (4, linebuf + 34 + 5 * i, &gottok);
904             }
905         }
906     }
907   while (!gottok);
908   for (i = 0; i < NUM_REGS; i++)
909     {
910       char swapped[2];
911
912       swapped[1] = reg[i];
913       swapped[0] = (reg[i]) >> 8;
914
915       supply_register (i, swapped);
916     }
917 }
918
919 /* Store register REGNO, or all if REGNO == -1.
920    Return errno value.  */
921 static void
922 hms_store_register (regno)
923      int regno;
924 {
925   if (regno == -1)
926     {
927       for (regno = 0; regno < NUM_REGS; regno++)
928         {
929           hms_store_register (regno);
930         }
931     }
932   else
933     {
934       char *name = get_reg_name (regno);
935       char buffer[100];
936
937       sprintf (buffer, "r %s=%x", name, read_register (regno));
938       hms_write_cr (buffer);
939       expect_prompt ();
940     }
941 }
942
943 /* Get ready to modify the registers array.  On machines which store
944    individual registers, this doesn't need to do anything.  On machines
945    which store all the registers in one fell swoop, this makes sure
946    that registers contains all the registers from the program being
947    debugged.  */
948
949 void
950 hms_prepare_to_store ()
951 {
952   /* Do nothing, since we can store individual regs */
953 }
954
955 static CORE_ADDR
956 translate_addr (addr)
957      CORE_ADDR addr;
958 {
959
960   return (addr);
961
962 }
963
964 /* Read a word from remote address ADDR and return it.
965  * This goes through the data cache.
966  */
967 int
968 hms_fetch_word (addr)
969      CORE_ADDR addr;
970 {
971   return dcache_fetch (addr);
972 }
973
974 /* Write a word WORD into remote address ADDR.
975    This goes through the data cache.  */
976
977 void
978 hms_store_word (addr, word)
979      CORE_ADDR addr;
980      int word;
981 {
982   dcache_poke (addr, word);
983 }
984
985 int
986 hms_xfer_inferior_memory (memaddr, myaddr, len, write, target)
987      CORE_ADDR memaddr;
988      char *myaddr;
989      int len;
990      int write;
991      struct target_ops *target; /* ignored */
992 {
993   register int i;
994
995   /* Round starting address down to longword boundary.  */
996   register CORE_ADDR addr;
997
998   /* Round ending address up; get number of longwords that makes.  */
999   register int count;
1000
1001   /* Allocate buffer of that many longwords.  */
1002   register int *buffer;
1003
1004   memaddr &= 0xffff;
1005   addr = memaddr & -sizeof (int);
1006   count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
1007
1008   buffer = (int *) alloca (count * sizeof (int));
1009
1010   if (write)
1011     {
1012       /* Fill start and end extra bytes of buffer with existing memory data.  */
1013
1014       if (addr != memaddr || len < (int) sizeof (int))
1015         {
1016           /* Need part of initial word -- fetch it.  */
1017           buffer[0] = hms_fetch_word (addr);
1018         }
1019
1020       if (count > 1)            /* FIXME, avoid if even boundary */
1021         {
1022           buffer[count - 1]
1023             = hms_fetch_word (addr + (count - 1) * sizeof (int));
1024         }
1025
1026       /* Copy data to be written over corresponding part of buffer */
1027
1028       memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
1029
1030       /* Write the entire buffer.  */
1031
1032       for (i = 0; i < count; i++, addr += sizeof (int))
1033         {
1034           errno = 0;
1035           hms_store_word (addr, buffer[i]);
1036           if (errno)
1037             {
1038
1039               return 0;
1040             }
1041
1042         }
1043     }
1044   else
1045     {
1046       /* Read all the longwords */
1047       for (i = 0; i < count; i++, addr += sizeof (int))
1048         {
1049           errno = 0;
1050           buffer[i] = hms_fetch_word (addr);
1051           if (errno)
1052             {
1053               return 0;
1054             }
1055           QUIT;
1056         }
1057
1058       /* Copy appropriate bytes out of the buffer.  */
1059       memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
1060     }
1061
1062   return len;
1063 }
1064
1065 int
1066 hms_write_inferior_memory (memaddr, myaddr, len)
1067      CORE_ADDR memaddr;
1068      unsigned char *myaddr;
1069      int len;
1070 {
1071   bfd_vma addr;
1072   int done;
1073   int todo;
1074
1075   done = 0;
1076   while (done < len)
1077     {
1078       char buffer[20];
1079       int thisgo;
1080       int idx;
1081
1082       thisgo = len - done;
1083       if (thisgo > 20)
1084         thisgo = 20;
1085
1086       sprintf (buffer, "M.B %4x =", memaddr + done);
1087       hms_write (buffer, 10);
1088       for (idx = 0; idx < thisgo; idx++)
1089         {
1090           char buf[20];
1091
1092           sprintf (buf, "%2x ", myaddr[idx + done]);
1093           hms_write (buf, 3);
1094         }
1095       hms_write_cr ("");
1096       expect_prompt ();
1097       done += thisgo;
1098     }
1099
1100 }
1101
1102 void
1103 hms_files_info ()
1104 {
1105   char *file = "nothing";
1106
1107   if (exec_bfd)
1108     file = bfd_get_filename (exec_bfd);
1109
1110   if (exec_bfd)
1111 #ifdef __GO32__
1112     printf_filtered ("\tAttached to DOS asynctsr and running program %s\n", file);
1113 #else
1114     printf_filtered ("\tAttached to %s at %d baud and running program %s\n", dev_name, baudrate, file);
1115 #endif
1116   printf_filtered ("\ton an H8/300 processor.\n");
1117 }
1118
1119 /* Copy LEN bytes of data from debugger memory at MYADDR
1120    to inferior's memory at MEMADDR.  Returns errno value.
1121  * sb/sh instructions don't work on unaligned addresses, when TU=1.
1122  */
1123
1124 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
1125    at debugger address MYADDR.  Returns errno value.  */
1126 int
1127 hms_read_inferior_memory (memaddr, myaddr, len)
1128      CORE_ADDR memaddr;
1129      char *myaddr;
1130      int len;
1131 {
1132   /* Align to nearest low 16 bits */
1133   int i;
1134
1135 #if 0
1136   CORE_ADDR start = memaddr & ~0xf;
1137   CORE_ADDR end = ((memaddr + len + 16) & ~0xf) - 1;
1138
1139 #endif
1140   CORE_ADDR start = memaddr;
1141   CORE_ADDR end = memaddr + len - 1;
1142
1143   int ok = 1;
1144
1145   /*
1146     AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1147     012345678901234567890123456789012345678901234567890123456789012345
1148     0         1         2         3         4         5         6
1149     */
1150   char buffer[66];
1151
1152   if (memaddr & 0xf)
1153     abort ();
1154   if (len != 16)
1155     abort ();
1156
1157   sprintf (buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
1158   hms_write_cr (buffer);
1159   /* drop the echo and newline*/
1160   for (i = 0; i < 13; i++)
1161     readchar ();
1162
1163   /* Grab the lines as they come out and fill the area */
1164   /* Skip over cr */
1165   while (1)
1166     {
1167       int p;
1168       int i;
1169       int addr;
1170       size_t idx;
1171
1172       char byte[16];
1173
1174       buffer[0] = readchar ();
1175       if (buffer[0] == 'M')
1176         break;
1177       for (i = 1; i < 66; i++)
1178         buffer[i] = readchar ();
1179
1180       /* Now parse the line */
1181
1182       addr = gethex (4, buffer, &ok);
1183       idx = 6;
1184       for (p = 0; p < 16; p += 2)
1185         {
1186           byte[p] = gethex (2, buffer + idx, &ok);
1187           byte[p + 1] = gethex (2, buffer + idx + 2, &ok);
1188           idx += 5;
1189
1190         }
1191
1192       for (p = 0; p < 16; p++)
1193         {
1194           if (addr + p >= memaddr &&
1195               addr + p < memaddr + len)
1196             {
1197               myaddr[(addr + p) - memaddr] = byte[p];
1198
1199             }
1200
1201         }
1202     }
1203   expect ("emory>");
1204   hms_write_cr (" ");
1205   expect_prompt ();
1206   return len;
1207 }
1208
1209 /* This routine is run as a hook, just before the main command loop is
1210    entered.  If gdb is configured for the H8, but has not had its
1211    target specified yet, this will loop prompting the user to do so.
1212 */
1213
1214 hms_before_main_loop ()
1215 {
1216   char ttyname[100];
1217   char *p, *p2;
1218   extern FILE *instream;
1219
1220   push_target (&hms_ops);
1221 }
1222
1223 #define MAX_BREAKS      16
1224 static int num_brkpts = 0;
1225 static int
1226 hms_insert_breakpoint (addr, save)
1227      CORE_ADDR addr;
1228      char *save;                /* Throw away, let hms save instructions */
1229 {
1230   check_open ();
1231
1232   if (num_brkpts < MAX_BREAKS)
1233     {
1234       char buffer[100];
1235
1236       num_brkpts++;
1237       sprintf (buffer, "b %x", addr & 0xffff);
1238       hms_write_cr (buffer);
1239       expect_prompt ();
1240       return (0);
1241     }
1242   else
1243     {
1244       fprintf_filtered (stderr,
1245                       "Too many break points, break point not installed\n");
1246       return (1);
1247     }
1248
1249 }
1250 static int
1251 hms_remove_breakpoint (addr, save)
1252      CORE_ADDR addr;
1253      char *save;                /* Throw away, let hms save instructions */
1254 {
1255   if (num_brkpts > 0)
1256     {
1257       char buffer[100];
1258
1259       num_brkpts--;
1260       sprintf (buffer, "b - %x", addr & 0xffff);
1261       hms_write_cr (buffer);
1262       expect_prompt ();
1263
1264     }
1265   return (0);
1266 }
1267
1268 /* Clear the hmss notion of what the break points are */
1269 static int
1270 hms_clear_breakpoints ()
1271 {
1272
1273   if (is_open)
1274     {
1275       hms_write_cr ("b -");
1276       expect_prompt ();
1277     }
1278   num_brkpts = 0;
1279 }
1280 static void
1281 hms_mourn ()
1282 {
1283   hms_clear_breakpoints ();
1284   unpush_target (&hms_ops);
1285   generic_mourn_inferior ();
1286 }
1287
1288 /* Put a command string, in args, out to the hms.  The hms is assumed to
1289    be in raw mode, all writing/reading done through desc.
1290    Ouput from the hms is placed on the users terminal until the
1291    prompt from the hms is seen.
1292    FIXME: Can't handle commands that take input.  */
1293
1294 void
1295 hms_com (args, fromtty)
1296      char *args;
1297      int fromtty;
1298 {
1299   check_open ();
1300
1301   if (!args)
1302     return;
1303
1304   /* Clear all input so only command relative output is displayed */
1305
1306   hms_write_cr (args);
1307   hms_write ("\030", 1);
1308   expect_prompt ();
1309 }
1310
1311 /* Define the target subroutine names */
1312
1313 struct target_ops hms_ops =
1314 {
1315   "hms", "Remote HMS monitor",
1316   "Use the H8 evaluation board running the HMS monitor connected\n\
1317 by a serial line.",
1318
1319   hms_open, hms_close,
1320   0, hms_detach, hms_resume, hms_wait,  /* attach */
1321   hms_fetch_register, hms_store_register,
1322   hms_prepare_to_store,
1323   hms_xfer_inferior_memory,
1324   hms_files_info,
1325   hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
1326   0, 0, 0, 0, 0,                /* Terminal handling */
1327   hms_kill,                     /* FIXME, kill */
1328   hms_load,
1329   0,                            /* lookup_symbol */
1330   hms_create_inferior,          /* create_inferior */
1331   hms_mourn,                    /* mourn_inferior FIXME */
1332   0,                            /* can_run */
1333   0,                            /* notice_signals */
1334   process_stratum, 0,           /* next */
1335   1, 1, 1, 1, 1,                /* all mem, mem, stack, regs, exec */
1336   0, 0,                         /* Section pointers */
1337   OPS_MAGIC,                    /* Always the last thing */
1338 };
1339
1340 hms_quiet ()
1341 {
1342   quiet = !quiet;
1343   if (quiet)
1344     printf_filtered ("Snoop disabled\n");
1345   else
1346     printf_filtered ("Snoop enabled\n");
1347
1348 }
1349
1350 hms_device (s)
1351      char *s;
1352 {
1353   if (s)
1354     {
1355       dev_name = get_word (&s);
1356     }
1357 }
1358
1359 static
1360 hms_speed (s)
1361      char *s;
1362 {
1363   check_open ();
1364
1365   if (s)
1366     {
1367       char buffer[100];
1368       int newrate = atoi (s);
1369       int which = 0;
1370
1371       if (SERIAL_SETBAUDRATE (desc, newrate))
1372         error ("Can't use %d baud\n", newrate);
1373
1374       printf_filtered ("Checking target is in sync\n");
1375
1376       printf_filtered ("Sending commands to set target to %d\n",
1377                        baudrate);
1378
1379       sprintf (buffer, "tm %d. N 8 1", baudrate);
1380       hms_write_cr (buffer);
1381     }
1382 }
1383
1384 /***********************************************************************/
1385
1386 void
1387 _initialize_remote_hms ()
1388 {
1389   add_target (&hms_ops);
1390
1391   add_com ("hms <command>", class_obscure, hms_com,
1392            "Send a command to the HMS monitor.");
1393   add_com ("snoop", class_obscure, hms_quiet,
1394            "Show what commands are going to the monitor");
1395
1396   add_com ("device", class_obscure, hms_device,
1397            "Set the terminal line for HMS communications");
1398
1399   add_com ("speed", class_obscure, hms_speed,
1400            "Set the terminal line speed for HMS communications");
1401
1402   dev_name = NULL;
1403 }
This page took 0.100341 seconds and 4 git commands to generate.