* remote-sim.c: first attempt at general simulator interface
[deliverable/binutils-gdb.git] / gdb / remote-hms.c
1 /* Remote debugging interface for Hitachi HMS Monitor Version 1.0
2 Copyright 1992 Free Software Foundation, Inc.
3 Contributed by Cygnus Support. Written by Steve Chamberlain
4 (sac@cygnus.com).
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22 #include "defs.h"
23 #include "inferior.h"
24 #include "wait.h"
25 #include "value.h"
26 #include <string.h>
27 #include <ctype.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 #include <setjmp.h>
31 #include <errno.h>
32 #include "terminal.h"
33 #include "target.h"
34 #include "gdbcore.h"
35
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 #define LINE_SIZE_POWER 4
62 #define LINE_SIZE (1<<LINE_SIZE_POWER) /* eg 1<<3 == 8 */
63 #define LINE_SIZE_MASK ((LINE_SIZE-1)) /* eg 7*2+1= 111*/
64 #define DCACHE_SIZE 64 /* Number of cache blocks */
65 #define XFORM(x) ((x&LINE_SIZE_MASK)>>2)
66 struct dcache_block
67 {
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 * I/O stuff stolen from remote-eb.c
224 ***********************************************************************/
225
226 static int timeout = 2;
227
228 static const char *dev_name;
229
230 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
231 hms_open knows that we don't have a file open when the program
232 starts. */
233
234 int is_open = 0;
235 int
236 check_open ()
237 {
238 if (!is_open)
239 {
240 error ("remote device not open");
241 }
242 }
243
244 #define ON 1
245 #define OFF 0
246
247 /* Read a character from the remote system, doing all the fancy
248 timeout stuff. */
249 static int
250 readchar ()
251 {
252 int buf;
253
254 buf = serial_readchar (timeout);
255
256 if (buf < 0)
257 error ("Timeout reading from remote system.");
258
259 if (!quiet)
260 printf ("%c", buf);
261
262 return buf & 0x7f;
263 }
264
265 static int
266 readchar_nofail ()
267 {
268 int buf;
269
270 buf = serial_readchar (timeout);
271 if (buf < 0)
272 buf = 0;
273 if (!quiet)
274 printf ("%c", buf);
275
276 return buf & 0x7f;
277
278 }
279
280 /* Keep discarding input from the remote system, until STRING is found.
281 Let the user break out immediately. */
282 static void
283 expect (string)
284 char *string;
285 {
286 char *p = string;
287
288 immediate_quit = 1;
289 while (1)
290 {
291 if (readchar () == *p)
292 {
293 p++;
294 if (*p == '\0')
295 {
296 immediate_quit = 0;
297 return;
298 }
299 }
300 else
301 p = string;
302 }
303 }
304
305 /* Keep discarding input until we see the hms prompt.
306
307 The convention for dealing with the prompt is that you
308 o give your command
309 o *then* wait for the prompt.
310
311 Thus the last thing that a procedure does with the serial line
312 will be an expect_prompt(). Exception: hms_resume does not
313 wait for the prompt, because the terminal is being handed over
314 to the inferior. However, the next thing which happens after that
315 is a hms_wait which does wait for the prompt.
316 Note that this includes abnormal exit, e.g. error(). This is
317 necessary to prevent getting into states from which we can't
318 recover. */
319 static void
320 expect_prompt ()
321 {
322 expect ("HMS>");
323 }
324
325 /* Get a hex digit from the remote system & return its value.
326 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
327 static int
328 get_hex_digit (ignore_space)
329 int ignore_space;
330 {
331 int ch;
332
333 while (1)
334 {
335 ch = readchar ();
336 if (ch >= '0' && ch <= '9')
337 return ch - '0';
338 else if (ch >= 'A' && ch <= 'F')
339 return ch - 'A' + 10;
340 else if (ch >= 'a' && ch <= 'f')
341 return ch - 'a' + 10;
342 else if (ch == ' ' && ignore_space)
343 ;
344 else
345 {
346 expect_prompt ();
347 error ("Invalid hex digit from remote system.");
348 }
349 }
350 }
351
352 /* Get a byte from hms_desc and put it in *BYT. Accept any number
353 leading spaces. */
354 static void
355 get_hex_byte (byt)
356 char *byt;
357 {
358 int val;
359
360 val = get_hex_digit (1) << 4;
361 val |= get_hex_digit (0);
362 *byt = val;
363 }
364
365 /* Read a 32-bit hex word from the hms, preceded by a space */
366 static long
367 get_hex_word ()
368 {
369 long val;
370 int j;
371
372 val = 0;
373 for (j = 0; j < 8; j++)
374 val = (val << 4) + get_hex_digit (j == 0);
375 return val;
376 }
377
378 /* Called when SIGALRM signal sent due to alarm() timeout. */
379
380 /* Number of SIGTRAPs we need to simulate. That is, the next
381 NEED_ARTIFICIAL_TRAP calls to hms_wait should just return
382 SIGTRAP without actually waiting for anything. */
383
384 static int need_artificial_trap = 0;
385
386 void
387 hms_kill (arg, from_tty)
388 char *arg;
389 int from_tty;
390 {
391
392 }
393
394 /*
395 * Download a file specified in 'args', to the hms.
396 */
397 static void
398 hms_load (args, fromtty)
399 char *args;
400 int fromtty;
401 {
402 bfd *abfd;
403 asection *s;
404 int n;
405 char buffer[1024];
406
407 check_open ();
408
409 dcache_flush ();
410 inferior_pid = 0;
411 abfd = bfd_openr (args, 0);
412 if (!abfd)
413 {
414 printf_filtered ("Unable to open file %s\n", args);
415 return;
416 }
417
418 if (bfd_check_format (abfd, bfd_object) == 0)
419 {
420 printf_filtered ("File is not an object file\n");
421 return;
422 }
423
424 s = abfd->sections;
425 while (s != (asection *) NULL)
426 {
427 if (s->flags & SEC_LOAD)
428 {
429 int i;
430
431 #define DELTA 1024
432 char *buffer = xmalloc (DELTA);
433
434 printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s->_raw_size);
435 for (i = 0; i < s->_raw_size; i += DELTA)
436 {
437 int delta = DELTA;
438
439 if (delta > s->_raw_size - i)
440 delta = s->_raw_size - i;
441
442 bfd_get_section_contents (abfd, s, buffer, i, delta);
443 hms_write_inferior_memory (s->vma + i, buffer, delta);
444 printf_filtered ("*");
445 fflush (stdout);
446 }
447 printf_filtered ("\n");
448 free (buffer);
449 }
450 s = s->next;
451 }
452 sprintf (buffer, "r PC=%x", abfd->start_address);
453 hms_write_cr (buffer);
454 expect_prompt ();
455 }
456
457 /* This is called not only when we first attach, but also when the
458 user types "run" after having attached. */
459 void
460 hms_create_inferior (execfile, args, env)
461 char *execfile;
462 char *args;
463 char **env;
464 {
465 int entry_pt;
466 char buffer[100];
467
468 if (args && *args)
469 error ("Can't pass arguments to remote hms process.");
470
471 if (execfile == 0 || exec_bfd == 0)
472 error ("No exec file specified");
473
474 entry_pt = (int) bfd_get_start_address (exec_bfd);
475 check_open ();
476
477 hms_kill (NULL, NULL);
478 hms_clear_breakpoints ();
479 init_wait_for_inferior ();
480 hms_write_cr ("");
481 expect_prompt ();
482
483 insert_breakpoints (); /* Needed to get correct instruction in cache */
484 proceed (entry_pt, -1, 0);
485 }
486
487 /* Open a connection to a remote debugger.
488 NAME is the filename used for communication, then a space,
489 then the baud rate.
490 */
491
492 static char *
493 find_end_of_word (s)
494 char *s;
495 {
496 while (*s && !isspace (*s))
497 s++;
498 return s;
499 }
500
501 static char *
502 get_word (p)
503 char **p;
504 {
505 char *s = *p;
506 char *word;
507 char *copy;
508 size_t len;
509
510 while (isspace (*s))
511 s++;
512
513 word = s;
514
515 len = 0;
516
517 while (*s && !isspace (*s))
518 {
519 s++;
520 len++;
521
522 }
523 copy = xmalloc (len + 1);
524 memcpy (copy, word, len);
525 copy[len] = 0;
526 *p = s;
527 return copy;
528 }
529
530 static int baudrate = 9600;
531
532 static int
533 is_baudrate_right ()
534 {
535 int ok;
536
537 /* Put this port into NORMAL mode, send the 'normal' character */
538
539 hms_write ("\001", 1); /* Control A */
540 hms_write ("\r", 1); /* Cr */
541
542 while (1)
543 {
544 ok = serial_readchar (timeout);
545 if (ok < 0)
546 break;
547 }
548
549 hms_write ("r", 1);
550
551 if (readchar_nofail () == 'r')
552 return 1;
553
554 /* Not the right baudrate, or the board's not on */
555 return 0;
556 }
557 static void
558 set_rate ()
559 {
560 if (!serial_setbaudrate (baudrate))
561 error ("Can't set baudrate");
562 }
563
564 static void
565 get_baudrate_right ()
566 {
567 #if 0
568 while (!is_baudrate_right ())
569 {
570 baudrate = serial_nextbaudrate (baudrate);
571 if (baudrate == 0)
572 {
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 #endif
581 }
582
583 static void
584 hms_open (name, from_tty)
585 char *name;
586 int from_tty;
587 {
588
589 unsigned int prl;
590 char *p;
591
592 if (name == 0)
593 {
594 name = "";
595 }
596 if (is_open)
597 hms_close (0);
598 if (name && strlen (name))
599 dev_name = strdup (name);
600 if (!serial_open (dev_name))
601 perror_with_name ((char *) dev_name);
602 serial_raw ();
603 is_open = 1;
604
605 dcache_init ();
606
607 get_baudrate_right ();
608
609 /* Hello? Are you there? */
610 serial_write ("\r", 1);
611 expect_prompt ();
612
613 /* Clear any break points */
614 hms_clear_breakpoints ();
615
616 printf_filtered ("Connected to remote H8/300 HMS system.\n");
617 }
618
619 /* Close out all files and local state before this target loses control. */
620
621 static void
622 hms_close (quitting)
623 int quitting;
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
693 /* It would be tempting to look for "\n[__exit + 0x8]\n"
694 but that requires loading symbols with "yc i" and even if
695 we did do that we don't know that the file has symbols. */
696 static char exitmsg[] = "HMS>";
697 char *bp = bpt;
698 char *ep = exitmsg;
699
700 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
701 char swallowed[50];
702
703 /* Current position in swallowed. */
704 char *swallowed_p = swallowed;
705
706 int ch;
707 int ch_handled;
708 int old_timeout = timeout;
709 int old_immediate_quit = immediate_quit;
710 int swallowed_cr = 0;
711
712 WSETEXIT ((*status), 0);
713
714 if (need_artificial_trap != 0)
715 {
716 WSETSTOP ((*status), SIGTRAP);
717 need_artificial_trap--;
718 return 0;
719 }
720
721 timeout = 99999; /* Don't time out -- user program is running. */
722 immediate_quit = 1; /* Helps ability to QUIT */
723 while (1)
724 {
725 QUIT; /* Let user quit and leave process running */
726 ch_handled = 0;
727 ch = readchar ();
728 if (ch == *bp)
729 {
730 bp++;
731 if (*bp == '\0')
732 break;
733 ch_handled = 1;
734
735 *swallowed_p++ = ch;
736 }
737 else
738 {
739 bp = bpt;
740 }
741 if (ch == *ep || *ep == '?')
742 {
743 ep++;
744 if (*ep == '\0')
745 break;
746
747 if (!ch_handled)
748 *swallowed_p++ = ch;
749 ch_handled = 1;
750 }
751 else
752 {
753 ep = exitmsg;
754 }
755
756 if (!ch_handled)
757 {
758 char *p;
759
760 /* Print out any characters which have been swallowed. */
761 for (p = swallowed; p < swallowed_p; ++p)
762 putc (*p, stdout);
763 swallowed_p = swallowed;
764
765 if ((ch != '\r' && ch != '\n') || swallowed_cr > 10)
766 {
767 putc (ch, stdout);
768 swallowed_cr = 10;
769 }
770 swallowed_cr++;
771
772 }
773 }
774 if (*bp == '\0')
775 {
776 WSETSTOP ((*status), SIGTRAP);
777 expect_prompt ();
778 }
779 else
780 {
781 WSETEXIT ((*status), 0);
782 }
783
784 timeout = old_timeout;
785 immediate_quit = old_immediate_quit;
786 return 0;
787 }
788
789 /* Return the name of register number REGNO
790 in the form input and output by hms.
791
792 Returns a pointer to a static buffer containing the answer. */
793 static char *
794 get_reg_name (regno)
795 int regno;
796 {
797 static char *rn[NUM_REGS] = REGISTER_NAMES;
798
799 return rn[regno];
800 }
801
802 /* Read the remote registers. */
803 static int
804 gethex (length, start, ok)
805 unsigned int length;
806 char *start;
807 int *ok;
808 {
809 int result = 0;
810
811 while (length--)
812 {
813 result <<= 4;
814 if (*start >= 'a' && *start <= 'f')
815 {
816 result += *start - 'a' + 10;
817 }
818 else if (*start >= 'A' && *start <= 'F')
819 {
820 result += *start - 'A' + 10;
821 }
822 else if (*start >= '0' && *start <= '9')
823 {
824 result += *start - '0';
825 }
826 else
827 *ok = 0;
828 start++;
829
830 }
831 return result;
832 }
833 static int
834 timed_read (buf, n, timeout)
835 char *buf;
836
837 {
838 int i;
839 char c;
840
841 i = 0;
842 while (i < n)
843 {
844 c = readchar ();
845
846 if (c == 0)
847 return i;
848 buf[i] = c;
849 i++;
850
851 }
852 return i;
853
854 }
855
856 hms_write (a, l)
857 char *a;
858 {
859 int i;
860
861 serial_write (a, l);
862
863 if (!quiet)
864 for (i = 0; i < l; i++)
865 {
866 printf ("%c", a[i]);
867 }
868 }
869
870 hms_write_cr (s)
871 char *s;
872 {
873 hms_write (s, strlen (s));
874 hms_write ("\r", 1);
875 }
876
877 static void
878 hms_fetch_register (dummy)
879 int dummy;
880 {
881 #define REGREPLY_SIZE 79
882 char linebuf[REGREPLY_SIZE + 1];
883 int i;
884 int s;
885 int gottok;
886
887 REGISTER_TYPE reg[NUM_REGS];
888 int foo[8];
889
890 check_open ();
891
892 do
893 {
894
895 hms_write_cr ("r");
896 s = timed_read (linebuf, REGREPLY_SIZE, 1);
897
898 linebuf[REGREPLY_SIZE] = 0;
899 gottok = 0;
900 if (linebuf[0] == 'r' &&
901 linebuf[3] == 'P' &&
902 linebuf[4] == 'C' &&
903 linebuf[5] == '=' &&
904 linebuf[75] == 'H' &&
905 linebuf[76] == 'M' &&
906 linebuf[77] == 'S')
907 {
908 /*
909 PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
910 5436789012345678901234567890123456789012345678901234567890123456789012
911 0 1 2 3 4 5 6
912 */
913 gottok = 1;
914
915 reg[PC_REGNUM] = gethex (4, linebuf + 6, &gottok);
916 reg[CCR_REGNUM] = gethex (2, linebuf + 15, &gottok);
917 for (i = 0; i < 8; i++)
918 {
919 reg[i] = gethex (4, linebuf + 34 + 5 * i, &gottok);
920 }
921 }
922 }
923 while (!gottok);
924 for (i = 0; i < NUM_REGS; i++)
925 {
926 char swapped[2];
927
928 swapped[1] = reg[i];
929 swapped[0] = (reg[i]) >> 8;
930
931 supply_register (i, swapped);
932 }
933 }
934
935 /* Store register REGNO, or all if REGNO == -1.
936 Return errno value. */
937 static void
938 hms_store_register (regno)
939 int regno;
940 {
941
942 /* printf("hms_store_register() called.\n"); fflush(stdout); /* */
943 if (regno == -1)
944 {
945 for (regno = 0; regno < NUM_REGS; regno++)
946 {
947 hms_store_register (regno);
948 }
949 }
950 else
951 {
952 char *name = get_reg_name (regno);
953 char buffer[100];
954
955 sprintf (buffer, "r %s=%x", name, read_register (regno));
956 hms_write_cr (buffer);
957 expect_prompt ();
958 }
959 }
960
961 /* Get ready to modify the registers array. On machines which store
962 individual registers, this doesn't need to do anything. On machines
963 which store all the registers in one fell swoop, this makes sure
964 that registers contains all the registers from the program being
965 debugged. */
966
967 void
968 hms_prepare_to_store ()
969 {
970 /* Do nothing, since we can store individual regs */
971 }
972
973 static CORE_ADDR
974 translate_addr (addr)
975 CORE_ADDR addr;
976 {
977
978 return (addr);
979
980 }
981
982 /* Read a word from remote address ADDR and return it.
983 * This goes through the data cache.
984 */
985 int
986 hms_fetch_word (addr)
987 CORE_ADDR addr;
988 {
989 return dcache_fetch (addr);
990 }
991
992 /* Write a word WORD into remote address ADDR.
993 This goes through the data cache. */
994
995 void
996 hms_store_word (addr, word)
997 CORE_ADDR addr;
998 int word;
999 {
1000 dcache_poke (addr, word);
1001 }
1002
1003 int
1004 hms_xfer_inferior_memory (memaddr, myaddr, len, write, target)
1005 CORE_ADDR memaddr;
1006 char *myaddr;
1007 int len;
1008 int write;
1009 struct target_ops *target; /* ignored */
1010 {
1011 register int i;
1012
1013 /* Round starting address down to longword boundary. */
1014 register CORE_ADDR addr;
1015
1016 /* Round ending address up; get number of longwords that makes. */
1017 register int count;
1018
1019 /* Allocate buffer of that many longwords. */
1020 register int *buffer;
1021
1022 memaddr &= 0xffff;
1023 addr = memaddr & -sizeof (int);
1024 count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
1025
1026 buffer = (int *) alloca (count * sizeof (int));
1027
1028 if (write)
1029 {
1030 /* Fill start and end extra bytes of buffer with existing memory data. */
1031
1032 if (addr != memaddr || len < (int) sizeof (int))
1033 {
1034 /* Need part of initial word -- fetch it. */
1035 buffer[0] = hms_fetch_word (addr);
1036 }
1037
1038 if (count > 1) /* FIXME, avoid if even boundary */
1039 {
1040 buffer[count - 1]
1041 = hms_fetch_word (addr + (count - 1) * sizeof (int));
1042 }
1043
1044 /* Copy data to be written over corresponding part of buffer */
1045
1046 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
1047
1048 /* Write the entire buffer. */
1049
1050 for (i = 0; i < count; i++, addr += sizeof (int))
1051 {
1052 errno = 0;
1053 hms_store_word (addr, buffer[i]);
1054 if (errno)
1055 {
1056
1057 return 0;
1058 }
1059
1060 }
1061 }
1062 else
1063 {
1064 /* Read all the longwords */
1065 for (i = 0; i < count; i++, addr += sizeof (int))
1066 {
1067 errno = 0;
1068 buffer[i] = hms_fetch_word (addr);
1069 if (errno)
1070 {
1071 return 0;
1072 }
1073 QUIT;
1074 }
1075
1076 /* Copy appropriate bytes out of the buffer. */
1077 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
1078 }
1079
1080 return len;
1081 }
1082
1083 int
1084 hms_write_inferior_memory (memaddr, myaddr, len)
1085 CORE_ADDR memaddr;
1086 unsigned char *myaddr;
1087 int len;
1088 {
1089 bfd_vma addr;
1090 int done;
1091 int todo;
1092
1093 done = 0;
1094 while (done < len)
1095 {
1096 char buffer[20];
1097 int thisgo;
1098 int idx;
1099
1100 thisgo = len - done;
1101 if (thisgo > 20)
1102 thisgo = 20;
1103
1104 sprintf (buffer, "M.B %4x =", memaddr + done);
1105 hms_write (buffer, 10);
1106 for (idx = 0; idx < thisgo; idx++)
1107 {
1108 char buf[20];
1109
1110 sprintf (buf, "%2x ", myaddr[idx + done]);
1111 hms_write (buf, 3);
1112 }
1113 hms_write_cr ("");
1114 expect_prompt ();
1115 done += thisgo;
1116 }
1117
1118 }
1119
1120 void
1121 hms_files_info ()
1122 {
1123 char *file = "nothing";
1124
1125 if (exec_bfd)
1126 file = bfd_get_filename (exec_bfd);
1127
1128 if (exec_bfd)
1129 #ifdef __GO32__
1130 printf_filtered ("\tAttached to DOS asynctsr and running program %s\n", file);
1131 #else
1132 printf_filtered ("\tAttached to %s at %d baud and running program %s\n", file);
1133 #endif
1134 printf_filtered ("\ton an H8/300 processor.\n");
1135 }
1136
1137 /* Copy LEN bytes of data from debugger memory at MYADDR
1138 to inferior's memory at MEMADDR. Returns errno value.
1139 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1140 */
1141
1142 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1143 at debugger address MYADDR. Returns errno value. */
1144 int
1145 hms_read_inferior_memory (memaddr, myaddr, len)
1146 CORE_ADDR memaddr;
1147 char *myaddr;
1148 int len;
1149 {
1150 /* Align to nearest low 16 bits */
1151 int i;
1152
1153 #if 0
1154 CORE_ADDR start = memaddr & ~0xf;
1155 CORE_ADDR end = ((memaddr + len + 16) & ~0xf) - 1;
1156
1157 #endif
1158 CORE_ADDR start = memaddr;
1159 CORE_ADDR end = memaddr + len - 1;
1160
1161 int ok = 1;
1162
1163 /*
1164 AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1165 012345678901234567890123456789012345678901234567890123456789012345
1166 0 1 2 3 4 5 6
1167 */
1168 char buffer[66];
1169
1170 if (memaddr & 0xf)
1171 abort ();
1172 if (len != 16)
1173 abort ();
1174
1175 sprintf (buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
1176 hms_write_cr (buffer);
1177 /* drop the echo and newline*/
1178 for (i = 0; i < 13; i++)
1179 readchar ();
1180
1181 /* Grab the lines as they come out and fill the area */
1182 /* Skip over cr */
1183 while (1)
1184 {
1185 int p;
1186 int i;
1187 int addr;
1188 size_t idx;
1189
1190 char byte[16];
1191
1192 buffer[0] = readchar ();
1193 if (buffer[0] == 'M')
1194 break;
1195 for (i = 1; i < 66; i++)
1196 buffer[i] = readchar ();
1197
1198 /* Now parse the line */
1199
1200 addr = gethex (4, buffer, &ok);
1201 idx = 6;
1202 for (p = 0; p < 16; p += 2)
1203 {
1204 byte[p] = gethex (2, buffer + idx, &ok);
1205 byte[p + 1] = gethex (2, buffer + idx + 2, &ok);
1206 idx += 5;
1207
1208 }
1209
1210 for (p = 0; p < 16; p++)
1211 {
1212 if (addr + p >= memaddr &&
1213 addr + p < memaddr + len)
1214 {
1215 myaddr[(addr + p) - memaddr] = byte[p];
1216
1217 }
1218
1219 }
1220 }
1221 hms_write_cr (" ");
1222 expect_prompt ();
1223 return len;
1224 }
1225
1226 /* This routine is run as a hook, just before the main command loop is
1227 entered. If gdb is configured for the H8, but has not had its
1228 target specified yet, this will loop prompting the user to do so.
1229 */
1230
1231 hms_before_main_loop ()
1232 {
1233 char ttyname[100];
1234 char *p, *p2;
1235 extern FILE *instream;
1236 extern jmp_buf to_top_level;
1237
1238 push_target (&hms_ops);
1239 }
1240
1241 #define MAX_BREAKS 16
1242 static int num_brkpts = 0;
1243 static int
1244 hms_insert_breakpoint (addr, save)
1245 CORE_ADDR addr;
1246 char *save; /* Throw away, let hms save instructions */
1247 {
1248 check_open ();
1249
1250 if (num_brkpts < MAX_BREAKS)
1251 {
1252 char buffer[100];
1253
1254 num_brkpts++;
1255 sprintf (buffer, "b %x", addr & 0xffff);
1256 hms_write_cr (buffer);
1257 expect_prompt ();
1258 return (0);
1259 }
1260 else
1261 {
1262 fprintf_filtered (stderr,
1263 "Too many break points, break point not installed\n");
1264 return (1);
1265 }
1266
1267 }
1268 static int
1269 hms_remove_breakpoint (addr, save)
1270 CORE_ADDR addr;
1271 char *save; /* Throw away, let hms save instructions */
1272 {
1273 if (num_brkpts > 0)
1274 {
1275 char buffer[100];
1276
1277 num_brkpts--;
1278 sprintf (buffer, "b - %x", addr & 0xffff);
1279 hms_write_cr (buffer);
1280 expect_prompt ();
1281
1282 }
1283 return (0);
1284 }
1285
1286 /* Clear the hmss notion of what the break points are */
1287 static int
1288 hms_clear_breakpoints ()
1289 {
1290
1291 if (is_open)
1292 {
1293 hms_write_cr ("b -");
1294 expect_prompt ();
1295 }
1296 num_brkpts = 0;
1297 }
1298 static void
1299 hms_mourn ()
1300 {
1301 hms_clear_breakpoints ();
1302 generic_mourn_inferior ();
1303 }
1304
1305 /* Put a command string, in args, out to the hms. The hms is assumed to
1306 be in raw mode, all writing/reading done through desc.
1307 Ouput from the hms is placed on the users terminal until the
1308 prompt from the hms is seen.
1309 FIXME: Can't handle commands that take input. */
1310
1311 void
1312 hms_com (args, fromtty)
1313 char *args;
1314 int fromtty;
1315 {
1316 check_open ();
1317
1318 if (!args)
1319 return;
1320
1321 /* Clear all input so only command relative output is displayed */
1322
1323 hms_write_cr (args);
1324 hms_write ("\030", 1);
1325 expect_prompt ();
1326 }
1327
1328 /* Define the target subroutine names */
1329
1330 struct target_ops hms_ops =
1331 {
1332 "hms", "Remote HMS monitor",
1333 "Use the H8 evaluation board running the HMS monitor connected\n\
1334 by a serial line.",
1335
1336 hms_open, hms_close,
1337 0, hms_detach, hms_resume, hms_wait, /* attach */
1338 hms_fetch_register, hms_store_register,
1339 hms_prepare_to_store,
1340 hms_xfer_inferior_memory,
1341 hms_files_info,
1342 hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
1343 0, 0, 0, 0, 0, /* Terminal handling */
1344 hms_kill, /* FIXME, kill */
1345 hms_load,
1346 0, /* lookup_symbol */
1347 hms_create_inferior, /* create_inferior */
1348 hms_mourn, /* mourn_inferior FIXME */
1349 0, /* can_run */
1350 0, /* notice_signals */
1351 process_stratum, 0, /* next */
1352 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1353 0, 0, /* Section pointers */
1354 OPS_MAGIC, /* Always the last thing */
1355 };
1356
1357 hms_quiet ()
1358 {
1359 quiet = !quiet;
1360 if (quiet)
1361 printf_filtered ("Snoop disabled\n");
1362 else
1363 printf_filtered ("Snoop enabled\n");
1364
1365 }
1366
1367 hms_device (s)
1368 char *s;
1369 {
1370 if (s)
1371 {
1372 dev_name = get_word (&s);
1373 }
1374 }
1375
1376 static
1377 hms_speed (s)
1378 char *s;
1379 {
1380 check_open ();
1381
1382 if (s)
1383 {
1384 char buffer[100];
1385 int newrate = atoi (s);
1386 int which = 0;
1387
1388 if (!serial_setbaudrate (newrate))
1389 error ("Can't use %d baud\n", newrate);
1390
1391 printf_filtered ("Checking target is in sync\n");
1392
1393 get_baudrate_right ();
1394 baudrate = newrate;
1395 printf_filtered ("Sending commands to set target to %d\n",
1396 baudrate);
1397
1398 sprintf (buffer, "tm %d. N 8 1", baudrate);
1399 hms_write_cr (buffer);
1400 }
1401 }
1402
1403 /***********************************************************************/
1404
1405 void
1406 _initialize_remote_hms ()
1407 {
1408 add_target (&hms_ops);
1409
1410 add_com ("hms <command>", class_obscure, hms_com,
1411 "Send a command to the HMS monitor.");
1412 add_com ("snoop", class_obscure, hms_quiet,
1413 "Show what commands are going to the monitor");
1414
1415 add_com ("device", class_obscure, hms_device,
1416 "Set the terminal line for HMS communications");
1417
1418 add_com ("speed", class_obscure, hms_speed,
1419 "Set the terminal line speed for HMS communications");
1420
1421 dev_name = NULL;
1422 }
This page took 0.057149 seconds and 4 git commands to generate.