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