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