]> Git Repo - binutils.git/blob - gdb/remote-hms.c
Split non-target-dependent code out of target_attach routines.
[binutils.git] / gdb / remote-hms.c
1 /* Remote debugging interface for Hitachi HMS Monitor Version 1.0
2    Copyright 1992 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.  Written by Steve Chamberlain
4    ([email protected]).
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
21
22 #include "defs.h"
23 #include "inferior.h"
24 #include "wait.h"
25 #include "value.h"
26 #include <string.h>
27 #include <ctype.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <setjmp.h>
31 #include <errno.h>
32 #include "terminal.h"
33 #include "target.h"
34 #include "gdbcore.h"
35
36 /* External data declarations */
37 extern int stop_soon_quietly;           /* for wait_for_inferior */
38
39 /* Forward data declarations */
40 extern struct target_ops hms_ops;               /* Forward declaration */
41
42 /* Forward function declarations */
43 static void hms_fetch_registers ();
44 static int  hms_store_registers ();
45 static void hms_close ();
46 static int  hms_clear_breakpoints();
47
48 extern struct target_ops hms_ops;
49
50 static int quiet = 1;
51
52 /***********************************************************************/
53 /* Caching stuff stolen from remote-nindy.c  */
54
55 /* The data cache records all the data read from the remote machine
56    since the last time it stopped.
57
58    Each cache block holds LINE_SIZE bytes of data
59    starting at a multiple-of-LINE_SIZE address.  */
60
61
62 #define LINE_SIZE_POWER 4
63 #define LINE_SIZE (1<<LINE_SIZE_POWER)     /* eg 1<<3 == 8 */
64 #define LINE_SIZE_MASK ((LINE_SIZE-1))      /* eg 7*2+1= 111*/
65 #define DCACHE_SIZE 64          /* Number of cache blocks */
66 #define XFORM(x)  ((x&LINE_SIZE_MASK)>>2)
67 struct dcache_block {
68         struct dcache_block *next, *last;
69         unsigned int addr;      /* Address for which data is recorded.  */
70         int data[LINE_SIZE/sizeof(int)];
71 };
72
73 struct dcache_block dcache_free, dcache_valid;
74
75 /* Free all the data cache blocks, thus discarding all cached data.  */ 
76 static
77 void
78 dcache_flush ()
79 {
80   register struct dcache_block *db;
81
82   while ((db = dcache_valid.next) != &dcache_valid)
83     {
84       remque (db);
85       insque (db, &dcache_free);
86     }
87 }
88
89 /*
90  * If addr is present in the dcache, return the address of the block
91  * containing it.
92  */
93 static
94 struct dcache_block *
95 dcache_hit (addr)
96      unsigned int addr;
97 {
98   register struct dcache_block *db;
99
100   if (addr & 3)
101     abort ();
102
103   /* Search all cache blocks for one that is at this address.  */
104   db = dcache_valid.next;
105   while (db != &dcache_valid)
106     {
107       if ((addr & ~LINE_SIZE_MASK)== db->addr)
108         return db;
109       db = db->next;
110     }
111   return NULL;
112 }
113
114 /*  Return the int data at address ADDR in dcache block DC.  */
115 static
116 int
117 dcache_value (db, addr)
118      struct dcache_block *db;
119      unsigned int addr;
120 {
121   if (addr & 3)
122     abort ();
123   return (db->data[XFORM(addr)]);
124 }
125
126 /* Get a free cache block, put or keep it on the valid list,
127    and return its address.  The caller should store into the block
128    the address and data that it describes, then remque it from the
129    free list and insert it into the valid list.  This procedure
130    prevents errors from creeping in if a ninMemGet is interrupted
131    (which used to put garbage blocks in the valid list...).  */
132 static
133 struct dcache_block *
134 dcache_alloc ()
135 {
136   register struct dcache_block *db;
137
138   if ((db = dcache_free.next) == &dcache_free)
139     {
140       /* If we can't get one from the free list, take last valid and put
141          it on the free list.  */
142       db = dcache_valid.last;
143       remque (db);
144       insque (db, &dcache_free);
145     }
146
147   remque (db);
148   insque (db, &dcache_valid);
149   return (db);
150 }
151
152 /* Return the contents of the word at address ADDR in the remote machine,
153    using the data cache.  */
154 static
155 int
156 dcache_fetch (addr)
157      CORE_ADDR addr;
158 {
159   register struct dcache_block *db;
160
161   db = dcache_hit (addr);
162   if (db == 0)
163     {
164       db = dcache_alloc ();
165       immediate_quit++;
166       hms_read_inferior_memory(addr & ~LINE_SIZE_MASK, (unsigned char *)db->data, LINE_SIZE);
167       immediate_quit--;
168       db->addr = addr & ~LINE_SIZE_MASK;
169       remque (db);                      /* Off the free list */
170       insque (db, &dcache_valid);       /* On the valid list */
171     }
172   return (dcache_value (db, addr));
173 }
174
175 /* Write the word at ADDR both in the data cache and in the remote machine.  */
176 static void
177 dcache_poke (addr, data)
178      CORE_ADDR addr;
179      int data;
180 {
181   register struct dcache_block *db;
182
183   /* First make sure the word is IN the cache.  DB is its cache block.  */
184   db = dcache_hit (addr);
185   if (db == 0)
186   {
187     db = dcache_alloc ();
188     immediate_quit++;
189     hms_write_inferior_memory(addr & ~LINE_SIZE_MASK, (unsigned char *)db->data, LINE_SIZE);
190     immediate_quit--;
191     db->addr = addr & ~LINE_SIZE_MASK;
192     remque (db);                /* Off the free list */
193     insque (db, &dcache_valid); /* On the valid list */
194   }
195
196   /* Modify the word in the cache.  */
197   db->data[XFORM(addr)] = data;
198
199   /* Send the changed word.  */
200   immediate_quit++;
201   hms_write_inferior_memory(addr, (unsigned char *)&data, 4);
202   immediate_quit--;
203 }
204
205 /* The cache itself. */
206 struct dcache_block the_cache[DCACHE_SIZE];
207
208 /* Initialize the data cache.  */
209 static void
210 dcache_init ()
211 {
212   register i;
213   register struct dcache_block *db;
214
215   db = the_cache;
216   dcache_free.next = dcache_free.last = &dcache_free;
217   dcache_valid.next = dcache_valid.last = &dcache_valid;
218   for (i=0;i<DCACHE_SIZE;i++,db++)
219     insque (db, &dcache_free);
220 }
221
222
223 /***********************************************************************
224  * I/O stuff stolen from remote-eb.c
225  ***********************************************************************/
226
227 static int timeout = 2;
228
229 static const char *dev_name;
230
231
232 /* Descriptor for I/O to remote machine.  Initialize it to -1 so that
233    hms_open knows that we don't have a file open when the program
234    starts.  */
235
236
237 int is_open = 0;
238 int check_open()
239 {
240   if (!is_open)
241   {
242     error("remote device not open");
243   }
244 }
245
246 #define ON      1
247 #define OFF     0
248
249 /* Read a character from the remote system, doing all the fancy
250    timeout stuff.  */
251 static int
252 readchar ()
253 {
254   int ok;
255   int buf;
256   buf = serial_timedreadchar(timeout, &ok);
257
258   if (!ok)
259    error ("Timeout reading from remote system.");
260
261   if (!quiet)
262    printf("%c",buf);
263   
264   return buf & 0x7f;
265 }
266
267 static int
268 readchar_nofail ()
269 {
270   int ok;
271   int buf;
272   buf = serial_timedreadchar(timeout, &ok);
273   if (!ok) buf = 0;
274   if (!quiet)
275    printf("%c",buf);
276   
277   return buf & 0x7f;
278
279 }
280
281 /* Keep discarding input from the remote system, until STRING is found. 
282    Let the user break out immediately.  */
283 static void
284 expect (string)
285      char *string;
286 {
287   char *p = string;
288
289
290   immediate_quit = 1;
291   while (1)
292     {
293       if (readchar() == *p)
294         {
295           p++;
296           if (*p == '\0')
297             {
298               immediate_quit = 0;
299               return;
300             }
301         }
302       else
303         p = string;
304     }
305 }
306
307 /* Keep discarding input until we see the hms prompt.
308
309    The convention for dealing with the prompt is that you
310    o give your command
311    o *then* wait for the prompt.
312
313    Thus the last thing that a procedure does with the serial line
314    will be an expect_prompt().  Exception:  hms_resume does not
315    wait for the prompt, because the terminal is being handed over
316    to the inferior.  However, the next thing which happens after that
317    is a hms_wait which does wait for the prompt.
318    Note that this includes abnormal exit, e.g. error().  This is
319    necessary to prevent getting into states from which we can't
320    recover.  */
321 static void
322 expect_prompt ()
323 {
324   expect ("HMS>");
325 }
326
327 /* Get a hex digit from the remote system & return its value.
328    If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
329 static int
330 get_hex_digit (ignore_space)
331      int ignore_space;
332 {
333   int ch;
334   while (1)
335     {
336       ch = readchar ();
337       if (ch >= '0' && ch <= '9')
338         return ch - '0';
339       else if (ch >= 'A' && ch <= 'F')
340         return ch - 'A' + 10;
341       else if (ch >= 'a' && ch <= 'f')
342         return ch - 'a' + 10;
343       else if (ch == ' ' && ignore_space)
344         ;
345       else
346         {
347           expect_prompt ();
348           error ("Invalid hex digit from remote system.");
349         }
350     }
351 }
352
353 /* Get a byte from hms_desc and put it in *BYT.  Accept any number
354    leading spaces.  */
355 static void
356 get_hex_byte (byt)
357      char *byt;
358 {
359   int val;
360
361   val = get_hex_digit (1) << 4;
362   val |= get_hex_digit (0);
363   *byt = val;
364 }
365
366 /* Read a 32-bit hex word from the hms, preceded by a space  */
367 static long 
368 get_hex_word()
369 {
370   long val;
371   int j;
372       
373   val = 0;
374   for (j = 0; j < 8; j++)
375         val = (val << 4) + get_hex_digit (j == 0);
376   return val;
377 }
378 /* Called when SIGALRM signal sent due to alarm() timeout.  */
379
380
381
382 /* Number of SIGTRAPs we need to simulate.  That is, the next
383    NEED_ARTIFICIAL_TRAP calls to hms_wait should just return
384    SIGTRAP without actually waiting for anything.  */
385
386 static int need_artificial_trap = 0;
387
388 void
389 hms_kill(arg,from_tty)
390 char    *arg;
391 int     from_tty;
392 {
393
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,"coff-h8300");
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       
436 #define DELTA 1024
437       char *buffer = xmalloc(DELTA);
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         if (delta > s->_raw_size - i)
443          delta = s->_raw_size - i ;
444
445         bfd_get_section_contents(abfd, s, buffer, i, delta);
446         hms_write_inferior_memory(s->vma + i, buffer, delta);
447         printf_filtered("*");
448         fflush(stdout);
449       }
450       printf_filtered(  "\n");      
451       free(buffer);
452     }
453     s = s->next;
454   }
455   sprintf(buffer, "r PC=%x", abfd->start_address);
456   hms_write_cr(buffer);
457   expect_prompt();
458 }
459
460 /* This is called not only when we first attach, but also when the
461    user types "run" after having attached.  */
462 void
463 hms_create_inferior (execfile, args, env)
464      char *execfile;
465      char *args;
466      char **env;
467 {
468   int entry_pt;
469   char buffer[100];    
470
471   if (args && *args)
472    error ("Can't pass arguments to remote hms process.");
473
474   if (execfile == 0 || exec_bfd == 0)
475    error ("No exec file specified");
476
477   entry_pt = (int) bfd_get_start_address (exec_bfd);
478   check_open();
479
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
492 /* Open a connection to a remote debugger.
493    NAME is the filename used for communication, then a space,
494    then the baud rate.
495  */
496
497 static char *
498 find_end_of_word(s)
499 char *s;
500 {
501   while (*s && !isspace(*s))
502    s++;
503   return s;
504 }
505
506 static char *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   /* Put this port into NORMAL mode, send the 'normal' character */
541
542   hms_write("\001", 1);         /* Control A */
543   hms_write("\r", 1);           /* Cr */
544   
545   while (1) 
546   {
547     serial_timedreadchar(timeout, &ok);
548     if (!ok) break;
549   }
550
551   hms_write("r",1);
552
553   if (readchar_nofail() == 'r')  
554    return 1;
555
556   /* Not the right baudrate, or the board's not on */
557   return 0;
558 }
559 static void
560 set_rate()
561 {
562   if (!serial_setbaudrate(baudrate))
563    error("Can't set baudrate");
564 }
565
566 static void
567 get_baudrate_right()
568 {
569   while (!is_baudrate_right()) 
570   {
571     baudrate = serial_nextbaudrate(baudrate);
572     if (baudrate == 0) {
573       printf_filtered("Board not yet in sync\n");
574       break;
575     }
576     printf_filtered("Board not responding, trying %d baud\n",baudrate);
577     QUIT;
578     serial_setbaudrate(baudrate);
579   }
580 }
581
582 static void
583 hms_open (name, from_tty)
584      char *name;
585      int from_tty;
586 {
587
588   unsigned int prl;
589   char *p;
590   
591   if(name == 0) 
592   {
593     name = "";
594   }
595   if (is_open)  
596     hms_close (0);
597   if (name && strlen(name))
598     dev_name = strdup(name);
599   if (!serial_open(dev_name))
600     perror_with_name ((char *)dev_name);
601   serial_raw();
602   is_open = 1;
603
604   dcache_init();
605
606   get_baudrate_right();
607   
608   /* Hello?  Are you there?  */
609   serial_write("\r",1);
610   expect_prompt ();
611
612   /* Clear any break points */
613   hms_clear_breakpoints();
614
615   printf_filtered("Connected to remote H8/300 HMS system.\n");
616 }
617
618 /* Close out all files and local state before this target loses control. */
619
620 static void
621 hms_close (quitting)
622      int quitting;
623 {
624
625
626   /* Clear any break points */
627   hms_clear_breakpoints();
628
629   /* Put this port back into REMOTE mode */ 
630   sleep(1);                     /* Let any output make it all the way back */
631   serial_write("R\r", 2);
632   serial_close();
633   is_open = 0;
634 }
635
636 /* Terminate the open connection to the remote debugger.
637    Use this when you want to detach and do something else
638    with your gdb.  */
639 void
640 hms_detach (args,from_tty)
641      char *args;
642      int from_tty;
643 {
644   if (is_open)
645   { 
646         hms_clear_breakpoints();
647   }
648  
649   pop_target();         /* calls hms_close to do the real work */
650   if (from_tty)
651     printf_filtered ("Ending remote %s debugging\n", target_shortname);
652 }
653  
654 /* Tell the remote machine to resume.  */
655
656 void
657 hms_resume (step, sig)
658      int step, sig;
659 {
660   dcache_flush();
661   
662   if (step)     
663   {
664     hms_write_cr("s");
665     expect("Step>");
666     
667     /* Force the next hms_wait to return a trap.  Not doing anything
668        about I/O from the target means that the user has to type
669        "continue" to see any.  FIXME, this should be fixed.  */
670     need_artificial_trap = 1;
671   }
672   else
673   {
674     hms_write_cr("g");
675     expect("g");
676   }
677 }
678
679 /* Wait until the remote machine stops, then return,
680    storing status in STATUS just as `wait' would.  */
681
682 int
683 hms_wait (status)
684      WAITTYPE *status;
685 {
686   /* Strings to look for.  '?' means match any single character.  
687      Note that with the algorithm we use, the initial character
688      of the string cannot recur in the string, or we will not
689      find some cases of the string in the input.  */
690   
691   static char bpt[] = "At breakpoint:";
692   /* It would be tempting to look for "\n[__exit + 0x8]\n"
693      but that requires loading symbols with "yc i" and even if
694      we did do that we don't know that the file has symbols.  */
695   static char exitmsg[] = "HMS>";
696   char *bp = bpt;
697   char *ep = exitmsg;
698
699   /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars.  */
700   char swallowed[50];
701   /* Current position in swallowed.  */
702   char *swallowed_p = swallowed;
703
704   int ch;
705   int ch_handled;
706   int old_timeout = timeout;
707   int old_immediate_quit = immediate_quit;
708   int swallowed_cr = 0;
709   
710   WSETEXIT ((*status), 0);
711
712   if (need_artificial_trap != 0)
713   {
714     WSETSTOP ((*status), SIGTRAP);
715     need_artificial_trap--;
716     return 0;
717   }
718
719   timeout = 99999;      /* Don't time out -- user program is running. */
720   immediate_quit = 1;           /* Helps ability to QUIT */
721   while (1) 
722   {
723     QUIT;                       /* Let user quit and leave process running */
724     ch_handled = 0;
725     ch = readchar ();
726     if (ch == *bp) 
727     {
728         bp++;
729         if (*bp == '\0')
730          break;
731         ch_handled = 1;
732
733         *swallowed_p++ = ch;
734       } 
735     else 
736     {
737       bp = bpt;
738     }
739     if (ch == *ep || *ep == '?') 
740     {
741         ep++;
742         if (*ep == '\0')
743          break;
744
745         if (!ch_handled)
746          *swallowed_p++ = ch;
747         ch_handled = 1;
748       } 
749     else 
750     {
751       ep = exitmsg;
752     }
753       
754     if (!ch_handled) {
755         char *p;
756         /* Print out any characters which have been swallowed.  */
757         for (p = swallowed; p < swallowed_p; ++p)
758          putc (*p, stdout);
759         swallowed_p = swallowed;
760
761           
762         if ((ch != '\r' && ch != '\n') || swallowed_cr>10) 
763         {
764           putc (ch, stdout);
765           swallowed_cr = 10;
766         }
767         swallowed_cr ++;
768           
769       }
770   }
771   if (*bp== '\0') 
772   {
773     WSETSTOP ((*status), SIGTRAP);
774     expect_prompt();
775   }
776   else 
777   {
778     WSETEXIT ((*status), 0);
779   }
780   
781   timeout = old_timeout;
782   immediate_quit = old_immediate_quit;
783   return 0;
784 }
785
786 /* Return the name of register number REGNO
787    in the form input and output by hms.
788
789    Returns a pointer to a static buffer containing the answer.  */
790 static char *
791 get_reg_name (regno)
792      int regno;
793 {
794   static  char *rn[NUM_REGS]= REGISTER_NAMES;
795   return rn[regno];
796 }
797
798 /* Read the remote registers.  */
799 static int gethex(length, start, ok)
800 unsigned int length;
801 char *start;
802 int *ok;
803 {
804   int result = 0;
805   while (length--)   
806   {
807     result <<= 4 ;
808     if (*start >='a' && *start <= 'f') 
809     {
810       result += *start - 'a' + 10;
811     }
812     else if (*start >='A' && *start <= 'F') 
813     {
814       result += *start - 'A' + 10;
815     }
816     else  if (*start >='0' && *start <= '9') 
817     {
818       result += *start - '0' ;
819     }
820     else *ok = 0;
821     start++;
822     
823   }
824   return result;
825 }
826 static int 
827 timed_read(buf, n, timeout)
828 char *buf;
829
830 {
831   int i;
832   char c;
833   i = 0;
834   while (i < n) 
835   {
836     c = readchar();
837     
838     if (c == 0) return i;
839     buf[i] = c;
840     i++;
841     
842   }
843   return i;  
844
845 }
846 hms_write(a,l)
847 char *a;
848 {
849   int i;
850   serial_write(a, l);
851
852   if (!quiet)
853    for (i = 0; i < l ; i++)
854    {
855      printf("%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   REGISTER_TYPE reg[NUM_REGS];
877   int foo[8];
878   check_open();
879   
880   do 
881   {
882     
883     hms_write_cr("r");
884     s = timed_read(linebuf, REGREPLY_SIZE, 1);
885
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     swapped[1] = reg[i];
917     swapped[0] = (reg[i])>> 8;
918
919     supply_register (i, swapped);
920   }  
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
931   /* printf("hms_store_register() called.\n"); fflush(stdout); /* */
932   if (regno == -1) 
933   {
934     for (regno = 0; regno < NUM_REGS; regno ++) 
935     {
936       hms_store_register(regno);
937     }
938   }
939   else
940   {
941     char *name = get_reg_name (regno);
942     char buffer[100];
943     sprintf(buffer,"r %s=%x", name, read_register(regno));
944     hms_write_cr(buffer);
945     expect_prompt();
946   }
947 }
948
949
950
951 /* Get ready to modify the registers array.  On machines which store
952    individual registers, this doesn't need to do anything.  On machines
953    which store all the registers in one fell swoop, this makes sure
954    that registers contains all the registers from the program being
955    debugged.  */
956
957 void
958 hms_prepare_to_store ()
959 {
960   /* Do nothing, since we can store individual regs */
961 }
962
963 static CORE_ADDR 
964 translate_addr(addr)
965 CORE_ADDR addr;
966 {
967
968         return(addr);
969
970 }
971
972 /* Read a word from remote address ADDR and return it.
973  * This goes through the data cache.
974  */
975 int
976 hms_fetch_word (addr)
977      CORE_ADDR addr;
978 {
979         return dcache_fetch (addr);
980 }
981
982 /* Write a word WORD into remote address ADDR.
983    This goes through the data cache.  */
984
985 void
986 hms_store_word (addr, word)
987      CORE_ADDR addr;
988      int word;
989 {
990         dcache_poke (addr, word);
991 }
992
993 int
994 hms_xfer_inferior_memory(memaddr, myaddr, len, write, target)
995      CORE_ADDR memaddr;
996      char *myaddr;
997      int len;
998      int write;
999      struct target_ops *target;                 /* ignored */
1000 {
1001   register int i;
1002   /* Round starting address down to longword boundary.  */
1003   register CORE_ADDR addr; 
1004   /* Round ending address up; get number of longwords that makes.  */
1005   register int count;
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
1014   buffer = (int *)alloca (count * sizeof (int));
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         /* Need part of initial word -- fetch it.  */
1021         buffer[0] = hms_fetch_word (addr);
1022       }
1023
1024     if (count > 1)              /* FIXME, avoid if even boundary */
1025     {
1026       buffer[count - 1]
1027        = hms_fetch_word (addr + (count - 1) * sizeof (int));
1028     }
1029
1030     /* Copy data to be written over corresponding part of buffer */
1031
1032     bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
1033
1034     /* Write the entire buffer.  */
1035
1036     for (i = 0; i < count; i++, addr += sizeof (int))
1037     {
1038       errno = 0;
1039       hms_store_word (addr, buffer[i]);
1040       if (errno) 
1041       {
1042         
1043         return 0;
1044       }
1045       
1046     }
1047   }
1048   else
1049   {
1050     /* Read all the longwords */
1051     for (i = 0; i < count; i++, addr += sizeof (int))
1052     {
1053       errno = 0;
1054       buffer[i] = hms_fetch_word (addr);
1055       if (errno) 
1056       {
1057         return 0;
1058       }
1059       QUIT;
1060     }
1061
1062     /* Copy appropriate bytes out of the buffer.  */
1063     bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
1064   }
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   done = 0;
1080   while(done < len) 
1081   {
1082     char buffer[20];
1083     int thisgo;
1084     int idx;
1085     thisgo = len - done;
1086     if (thisgo > 20) thisgo = 20;
1087
1088     sprintf(buffer,"M.B %4x =", memaddr+done);
1089     hms_write(buffer,10);
1090     for (idx = 0; idx < thisgo; idx++) 
1091     {
1092       char buf[20];
1093       sprintf(buf, "%2x ", myaddr[idx+done]); 
1094       hms_write(buf, 3);
1095     }
1096     hms_write_cr("");
1097     expect_prompt();
1098     done += thisgo;
1099   }
1100
1101
1102 }
1103
1104 void
1105 hms_files_info ()
1106 {
1107 char *file = "nothing";
1108 if (exec_bfd)
1109  file = bfd_get_filename(exec_bfd);
1110
1111 if (exec_bfd)
1112 #ifdef __GO32__
1113    printf_filtered("\tAttached to DOS asynctsr and running program %s\n",file);
1114 #else
1115   printf_filtered("\tAttached to %s at %d baud and running program %s\n",file);
1116 #endif
1117   printf_filtered("\ton an H8/300 processor.\n");
1118 }
1119
1120 /* Copy LEN bytes of data from debugger memory at MYADDR
1121    to inferior's memory at MEMADDR.  Returns errno value.  
1122  * sb/sh instructions don't work on unaligned addresses, when TU=1. 
1123  */
1124
1125
1126 /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
1127    at debugger address MYADDR.  Returns errno value.  */
1128 int
1129 hms_read_inferior_memory(memaddr, myaddr, len)
1130      CORE_ADDR memaddr;
1131      char *myaddr;
1132      int len;
1133 {
1134   /* Align to nearest low 16 bits */
1135   int i;
1136                                     
1137 #if 0
1138   CORE_ADDR start = memaddr & ~0xf;
1139   CORE_ADDR end = ((memaddr + len +16) & ~0xf) -1;
1140 #endif
1141   CORE_ADDR start = memaddr;
1142   CORE_ADDR end = memaddr + len -1;
1143   
1144   int ok =1;
1145   
1146   /*
1147     AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1148     012345678901234567890123456789012345678901234567890123456789012345
1149     0         1         2         3         4         5         6
1150     */
1151   char buffer[66];
1152   if (memaddr & 0xf) abort();
1153   if (len != 16) abort();
1154   
1155   sprintf(buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
1156   hms_write_cr(buffer);
1157   /* drop the echo and newline*/
1158   for (i = 0; i < 13; i++)
1159    readchar();
1160   
1161
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     buffer[0] = readchar();
1174     if (buffer[0] == 'M') 
1175      break;
1176     for (i = 1; i < 66; i++)
1177      buffer[i] = readchar();
1178     
1179     /* Now parse the line */
1180
1181     addr = gethex(4, buffer, &ok);
1182     idx = 6;
1183     for (p = 0; p < 16; p+=2) 
1184     {
1185       byte[p] = gethex(2, buffer + idx, &ok);
1186       byte[p+1] = gethex(2, buffer+ idx + 2, &ok);
1187       idx+=5;
1188       
1189     }
1190
1191     
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   hms_write_cr(" ");
1204   expect_prompt();
1205   return len;
1206 }
1207
1208 /* This routine is run as a hook, just before the main command loop is
1209    entered.  If gdb is configured for the H8, but has not had its
1210    target specified yet, this will loop prompting the user to do so.
1211 */
1212
1213 hms_before_main_loop ()
1214 {
1215   char ttyname[100];
1216   char *p, *p2;
1217   extern FILE *instream;
1218   extern jmp_buf to_top_level;
1219
1220   push_target (&hms_ops);
1221 }
1222
1223
1224 #define MAX_BREAKS      16
1225 static int num_brkpts=0;
1226 static int
1227 hms_insert_breakpoint(addr, save)
1228 CORE_ADDR       addr;
1229 char            *save;  /* Throw away, let hms save instructions */
1230 {
1231   check_open();
1232   
1233   if (num_brkpts < MAX_BREAKS) 
1234   {
1235     char buffer[100];
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 }
1251 static int
1252 hms_remove_breakpoint(addr, save)
1253 CORE_ADDR       addr;
1254 char            *save;  /* Throw away, let hms save instructions */
1255 {
1256   if (num_brkpts > 0) 
1257   {
1258     char buffer[100];
1259       
1260     num_brkpts--;
1261     sprintf(buffer,"b - %x", addr & 0xffff);
1262     hms_write_cr(buffer);
1263     expect_prompt();
1264       
1265   }
1266   return(0);
1267 }
1268
1269 /* Clear the hmss notion of what the break points are */
1270 static int
1271 hms_clear_breakpoints() 
1272
1273
1274   if (is_open) {
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   generic_mourn_inferior ();
1285 }
1286
1287
1288
1289 /* Put a command string, in args, out to the hms.  The hms is assumed to
1290    be in raw mode, all writing/reading done through desc.
1291    Ouput from the hms is placed on the users terminal until the
1292    prompt from the hms is seen.
1293    FIXME: Can't handle commands that take input.  */
1294
1295 void
1296 hms_com (args, fromtty)
1297      char       *args;
1298      int        fromtty;
1299 {
1300   check_open();
1301   
1302   if (!args) 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         "hms", "Remote HMS monitor",
1315 "Use the H8 evaluation board running the HMS monitor connected\n\
1316 by a serial line.",
1317
1318         hms_open, hms_close, 
1319         0, hms_detach, hms_resume, hms_wait,    /* attach */
1320         hms_fetch_register, hms_store_register,
1321         hms_prepare_to_store,
1322         hms_xfer_inferior_memory, 
1323         hms_files_info,
1324         hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
1325         0, 0, 0, 0, 0,          /* Terminal handling */
1326         hms_kill,               /* FIXME, kill */
1327         hms_load, 
1328         0,                      /* lookup_symbol */
1329         hms_create_inferior,    /* create_inferior */ 
1330         hms_mourn,              /* mourn_inferior FIXME */
1331         0,                      /* can_run */
1332         process_stratum, 0, /* next */
1333         1, 1, 1, 1, 1,  /* all mem, mem, stack, regs, exec */
1334         0,0,            /* Section pointers */
1335         OPS_MAGIC,              /* Always the last thing */
1336 };
1337
1338
1339 hms_quiet()
1340 {
1341  quiet = ! quiet;  
1342    if (quiet)
1343      printf_filtered("Snoop disabled\n");
1344    else
1345      printf_filtered("Snoop enabled\n");
1346
1347 }
1348
1349 hms_device(s)
1350 char *s;
1351 {
1352   if (s) 
1353   {
1354     dev_name = get_word(&s);
1355   }  
1356 }
1357
1358
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     if (!serial_setbaudrate(newrate))
1371         error("Can't use %d baud\n", newrate);
1372     
1373     printf_filtered("Checking target is in sync\n");
1374     
1375     get_baudrate_right();
1376     baudrate = newrate;
1377     printf_filtered("Sending commands to set target to %d\n",
1378                     baudrate);    
1379     
1380     sprintf(buffer, "tm %d. N 8 1", baudrate);
1381     hms_write_cr(buffer);
1382   }    
1383 }
1384
1385 /***********************************************************************/
1386
1387 void
1388 _initialize_remote_hms ()
1389 {
1390   add_target (&hms_ops);
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 = serial_default_name();
1403 }
1404
1405
This page took 0.0971 seconds and 4 git commands to generate.