126babc5f1daf0b84a79bc2ce2dd2a51a1dab04c
[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 #include "serial.h"
36
37 /* External data declarations */
38 extern int stop_soon_quietly; /* for wait_for_inferior */
39
40 /* Forward data declarations */
41 extern struct target_ops hms_ops; /* Forward declaration */
42
43 /* Forward function declarations */
44 static void hms_fetch_registers ();
45 static int hms_store_registers ();
46 static void hms_close ();
47 static int hms_clear_breakpoints ();
48
49 extern struct target_ops hms_ops;
50
51 static int quiet = 1;
52
53
54 serial_t desc;
55
56 /***********************************************************************/
57 /* Caching stuff stolen from remote-nindy.c */
58
59 /* The data cache records all the data read from the remote machine
60 since the last time it stopped.
61
62 Each cache block holds LINE_SIZE bytes of data
63 starting at a multiple-of-LINE_SIZE address. */
64
65 #define LINE_SIZE_POWER 4
66 #define LINE_SIZE (1<<LINE_SIZE_POWER) /* eg 1<<3 == 8 */
67 #define LINE_SIZE_MASK ((LINE_SIZE-1)) /* eg 7*2+1= 111*/
68 #define DCACHE_SIZE 64 /* Number of cache blocks */
69 #define XFORM(x) ((x&LINE_SIZE_MASK)>>2)
70 struct dcache_block
71 {
72 struct dcache_block *next, *last;
73 unsigned int addr; /* Address for which data is recorded. */
74 int data[LINE_SIZE / sizeof (int)];
75 };
76
77 struct dcache_block dcache_free, dcache_valid;
78
79 /* Free all the data cache blocks, thus discarding all cached data. */
80 static
81 void
82 dcache_flush ()
83 {
84 register struct dcache_block *db;
85
86 while ((db = dcache_valid.next) != &dcache_valid)
87 {
88 remque (db);
89 insque (db, &dcache_free);
90 }
91 }
92
93 /*
94 * If addr is present in the dcache, return the address of the block
95 * containing it.
96 */
97 static
98 struct dcache_block *
99 dcache_hit (addr)
100 unsigned int addr;
101 {
102 register struct dcache_block *db;
103
104 if (addr & 3)
105 abort ();
106
107 /* Search all cache blocks for one that is at this address. */
108 db = dcache_valid.next;
109 while (db != &dcache_valid)
110 {
111 if ((addr & ~LINE_SIZE_MASK) == db->addr)
112 return db;
113 db = db->next;
114 }
115 return NULL;
116 }
117
118 /* Return the int data at address ADDR in dcache block DC. */
119 static
120 int
121 dcache_value (db, addr)
122 struct dcache_block *db;
123 unsigned int addr;
124 {
125 if (addr & 3)
126 abort ();
127 return (db->data[XFORM (addr)]);
128 }
129
130 /* Get a free cache block, put or keep it on the valid list,
131 and return its address. The caller should store into the block
132 the address and data that it describes, then remque it from the
133 free list and insert it into the valid list. This procedure
134 prevents errors from creeping in if a ninMemGet is interrupted
135 (which used to put garbage blocks in the valid list...). */
136 static
137 struct dcache_block *
138 dcache_alloc ()
139 {
140 register struct dcache_block *db;
141
142 if ((db = dcache_free.next) == &dcache_free)
143 {
144 /* If we can't get one from the free list, take last valid and put
145 it on the free list. */
146 db = dcache_valid.last;
147 remque (db);
148 insque (db, &dcache_free);
149 }
150
151 remque (db);
152 insque (db, &dcache_valid);
153 return (db);
154 }
155
156 /* Return the contents of the word at address ADDR in the remote machine,
157 using the data cache. */
158 static
159 int
160 dcache_fetch (addr)
161 CORE_ADDR addr;
162 {
163 register struct dcache_block *db;
164
165 db = dcache_hit (addr);
166 if (db == 0)
167 {
168 db = dcache_alloc ();
169 immediate_quit++;
170 hms_read_inferior_memory (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE);
171 immediate_quit--;
172 db->addr = addr & ~LINE_SIZE_MASK;
173 remque (db); /* Off the free list */
174 insque (db, &dcache_valid); /* On the valid list */
175 }
176 return (dcache_value (db, addr));
177 }
178
179 /* Write the word at ADDR both in the data cache and in the remote machine. */
180 static void
181 dcache_poke (addr, data)
182 CORE_ADDR addr;
183 int data;
184 {
185 register struct dcache_block *db;
186
187 /* First make sure the word is IN the cache. DB is its cache block. */
188 db = dcache_hit (addr);
189 if (db == 0)
190 {
191 db = dcache_alloc ();
192 immediate_quit++;
193 hms_write_inferior_memory (addr & ~LINE_SIZE_MASK, (unsigned char *) db->data, LINE_SIZE);
194 immediate_quit--;
195 db->addr = addr & ~LINE_SIZE_MASK;
196 remque (db); /* Off the free list */
197 insque (db, &dcache_valid); /* On the valid list */
198 }
199
200 /* Modify the word in the cache. */
201 db->data[XFORM (addr)] = data;
202
203 /* Send the changed word. */
204 immediate_quit++;
205 hms_write_inferior_memory (addr, (unsigned char *) &data, 4);
206 immediate_quit--;
207 }
208
209 /* The cache itself. */
210 struct dcache_block the_cache[DCACHE_SIZE];
211
212 /* Initialize the data cache. */
213 static void
214 dcache_init ()
215 {
216 register i;
217 register struct dcache_block *db;
218
219 db = the_cache;
220 dcache_free.next = dcache_free.last = &dcache_free;
221 dcache_valid.next = dcache_valid.last = &dcache_valid;
222 for (i = 0; i < DCACHE_SIZE; i++, db++)
223 insque (db, &dcache_free);
224 }
225
226 /***********************************************************************
227 * I/O stuff stolen from remote-eb.c
228 ***********************************************************************/
229
230 static int timeout = 2;
231
232 static const char *dev_name;
233
234 /* Descriptor for I/O to remote machine. Initialize it to -1 so that
235 hms_open knows that we don't have a file open when the program
236 starts. */
237
238 int is_open = 0;
239 int
240 check_open ()
241 {
242 if (!is_open)
243 {
244 error ("remote device not open");
245 }
246 }
247
248 #define ON 1
249 #define OFF 0
250
251 /* Read a character from the remote system, doing all the fancy
252 timeout stuff. */
253 static int
254 readchar ()
255 {
256 int buf;
257
258 buf = SERIAL_READCHAR (desc, timeout);
259
260 if (buf == SERIAL_TIMEOUT)
261 error ("Timeout reading from remote system.");
262
263 if (!quiet)
264 printf ("%c", buf);
265
266 return buf & 0x7f;
267 }
268
269 static int
270 readchar_nofail ()
271 {
272 int buf;
273
274 buf = SERIAL_READCHAR (desc, timeout);
275 if (buf == SERIAL_TIMEOUT)
276 buf = 0;
277 if (!quiet)
278 printf ("%c", buf);
279
280 return buf & 0x7f;
281
282 }
283
284 /* Keep discarding input from the remote system, until STRING is found.
285 Let the user break out immediately. */
286 static void
287 expect (string)
288 char *string;
289 {
290 char *p = string;
291
292 immediate_quit = 1;
293 while (1)
294 {
295 if (readchar () == *p)
296 {
297 p++;
298 if (*p == '\0')
299 {
300 immediate_quit = 0;
301 return;
302 }
303 }
304 else
305 p = string;
306 }
307 }
308
309 /* Keep discarding input until we see the hms prompt.
310
311 The convention for dealing with the prompt is that you
312 o give your command
313 o *then* wait for the prompt.
314
315 Thus the last thing that a procedure does with the serial line
316 will be an expect_prompt(). Exception: hms_resume does not
317 wait for the prompt, because the terminal is being handed over
318 to the inferior. However, the next thing which happens after that
319 is a hms_wait which does wait for the prompt.
320 Note that this includes abnormal exit, e.g. error(). This is
321 necessary to prevent getting into states from which we can't
322 recover. */
323 static void
324 expect_prompt ()
325 {
326 expect ("HMS>");
327 }
328
329 /* Get a hex digit from the remote system & return its value.
330 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
331 static int
332 get_hex_digit (ignore_space)
333 int ignore_space;
334 {
335 int ch;
336
337 while (1)
338 {
339 ch = readchar ();
340 if (ch >= '0' && ch <= '9')
341 return ch - '0';
342 else if (ch >= 'A' && ch <= 'F')
343 return ch - 'A' + 10;
344 else if (ch >= 'a' && ch <= 'f')
345 return ch - 'a' + 10;
346 else if (ch == ' ' && ignore_space)
347 ;
348 else
349 {
350 expect_prompt ();
351 error ("Invalid hex digit from remote system.");
352 }
353 }
354 }
355
356 /* Get a byte from hms_desc and put it in *BYT. Accept any number
357 leading spaces. */
358 static void
359 get_hex_byte (byt)
360 char *byt;
361 {
362 int val;
363
364 val = get_hex_digit (1) << 4;
365 val |= get_hex_digit (0);
366 *byt = val;
367 }
368
369 /* Read a 32-bit hex word from the hms, preceded by a space */
370 static long
371 get_hex_word ()
372 {
373 long val;
374 int j;
375
376 val = 0;
377 for (j = 0; j < 8; j++)
378 val = (val << 4) + get_hex_digit (j == 0);
379 return val;
380 }
381
382 /* Called when SIGALRM signal sent due to alarm() timeout. */
383
384 /* Number of SIGTRAPs we need to simulate. That is, the next
385 NEED_ARTIFICIAL_TRAP calls to hms_wait should just return
386 SIGTRAP without actually waiting for anything. */
387
388 static int need_artificial_trap = 0;
389
390 void
391 hms_kill (arg, from_tty)
392 char *arg;
393 int from_tty;
394 {
395
396 }
397
398 /*
399 * Download a file specified in 'args', to the hms.
400 */
401 static void
402 hms_load (args, fromtty)
403 char *args;
404 int fromtty;
405 {
406 bfd *abfd;
407 asection *s;
408 int n;
409 char buffer[1024];
410
411 check_open ();
412
413 dcache_flush ();
414 inferior_pid = 0;
415 abfd = bfd_openr (args, gnutarget);
416 if (!abfd)
417 {
418 printf_filtered ("Unable to open file %s\n", args);
419 return;
420 }
421
422 if (bfd_check_format (abfd, bfd_object) == 0)
423 {
424 printf_filtered ("File is not an object file\n");
425 return;
426 }
427
428 s = abfd->sections;
429 while (s != (asection *) NULL)
430 {
431 if (s->flags & SEC_LOAD)
432 {
433 int i;
434
435 #define DELTA 1024
436 char *buffer = xmalloc (DELTA);
437
438 printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s->_raw_size);
439 for (i = 0; i < s->_raw_size; i += DELTA)
440 {
441 int delta = DELTA;
442
443 if (delta > s->_raw_size - i)
444 delta = s->_raw_size - i;
445
446 bfd_get_section_contents (abfd, s, buffer, i, delta);
447 hms_write_inferior_memory (s->vma + i, buffer, delta);
448 printf_filtered ("*");
449 fflush (stdout);
450 }
451 printf_filtered ("\n");
452 free (buffer);
453 }
454 s = s->next;
455 }
456 sprintf (buffer, "r PC=%x", abfd->start_address);
457 hms_write_cr (buffer);
458 expect_prompt ();
459 }
460
461 /* This is called not only when we first attach, but also when the
462 user types "run" after having attached. */
463 void
464 hms_create_inferior (execfile, args, env)
465 char *execfile;
466 char *args;
467 char **env;
468 {
469 int entry_pt;
470 char buffer[100];
471
472 if (args && *args)
473 error ("Can't pass arguments to remote hms process.");
474
475 if (execfile == 0 || exec_bfd == 0)
476 error ("No exec file specified");
477
478 entry_pt = (int) bfd_get_start_address (exec_bfd);
479 check_open ();
480
481 hms_kill (NULL, NULL);
482 hms_clear_breakpoints ();
483 init_wait_for_inferior ();
484 hms_write_cr ("");
485 expect_prompt ();
486
487 insert_breakpoints (); /* Needed to get correct instruction in cache */
488 proceed (entry_pt, -1, 0);
489 }
490
491 /* Open a connection to a remote debugger.
492 NAME is the filename used for communication, then a space,
493 then the baud rate.
494 */
495
496 static char *
497 find_end_of_word (s)
498 char *s;
499 {
500 while (*s && !isspace (*s))
501 s++;
502 return s;
503 }
504
505 static char *
506 get_word (p)
507 char **p;
508 {
509 char *s = *p;
510 char *word;
511 char *copy;
512 size_t len;
513
514 while (isspace (*s))
515 s++;
516
517 word = s;
518
519 len = 0;
520
521 while (*s && !isspace (*s))
522 {
523 s++;
524 len++;
525
526 }
527 copy = xmalloc (len + 1);
528 memcpy (copy, word, len);
529 copy[len] = 0;
530 *p = s;
531 return copy;
532 }
533
534 static int baudrate = 9600;
535
536 static int
537 is_baudrate_right ()
538 {
539 int ok;
540
541 /* Put this port into NORMAL mode, send the 'normal' character */
542
543 hms_write ("\001", 1); /* Control A */
544 hms_write ("\r", 1); /* Cr */
545
546 while (1)
547 {
548 ok = SERIAL_READCHAR (desc, timeout);
549 if (ok < 0)
550 break;
551 }
552
553 hms_write ("r", 1);
554
555 if (readchar_nofail () == 'r')
556 return 1;
557
558 /* Not the right baudrate, or the board's not on */
559 return 0;
560 }
561 static void
562 set_rate ()
563 {
564 if (!SERIAL_SETBAUDRATE (desc, baudrate))
565 error ("Can't set baudrate");
566 }
567
568
569 static void
570 hms_open (name, from_tty)
571 char *name;
572 int from_tty;
573 {
574 unsigned int prl;
575 char *p;
576
577 if (name == 0)
578 {
579 name = "";
580 }
581 if (is_open)
582 hms_close (0);
583 dev_name = strdup (name);
584
585 if (!(desc = SERIAL_OPEN (dev_name)))
586 perror_with_name ((char *) dev_name);
587
588 SERIAL_RAW (desc);
589 is_open = 1;
590
591 dcache_init ();
592
593 /* Hello? Are you there? */
594 SERIAL_WRITE (desc, "\r", 1);
595 expect_prompt ();
596
597 /* Clear any break points */
598 hms_clear_breakpoints ();
599
600 printf_filtered ("Connected to remote H8/300 HMS system.\n");
601 }
602
603 /* Close out all files and local state before this target loses control. */
604
605 static void
606 hms_close (quitting)
607 int quitting;
608 {
609 /* Clear any break points */
610 hms_clear_breakpoints ();
611 sleep (1); /* Let any output make it all the way back */
612 if (is_open)
613 {
614 SERIAL_WRITE (desc, "R\r", 2);
615 SERIAL_CLOSE (desc);
616 }
617 is_open = 0;
618 }
619
620 /* Terminate the open connection to the remote debugger.
621 Use this when you want to detach and do something else
622 with your gdb. */
623 void
624 hms_detach (args, from_tty)
625 char *args;
626 int from_tty;
627 {
628 if (is_open)
629 {
630 hms_clear_breakpoints ();
631 }
632
633 pop_target (); /* calls hms_close to do the real work */
634 if (from_tty)
635 printf_filtered ("Ending remote %s debugging\n", target_shortname);
636 }
637
638 /* Tell the remote machine to resume. */
639
640 void
641 hms_resume (pid, step, sig)
642 int pid, step, sig;
643 {
644 dcache_flush ();
645
646 if (step)
647 {
648 hms_write_cr ("s");
649 expect ("Step>");
650
651 /* Force the next hms_wait to return a trap. Not doing anything
652 about I/O from the target means that the user has to type
653 "continue" to see any. FIXME, this should be fixed. */
654 need_artificial_trap = 1;
655 }
656 else
657 {
658 hms_write_cr ("g");
659 expect ("g");
660 }
661 }
662
663 /* Wait until the remote machine stops, then return,
664 storing status in STATUS just as `wait' would. */
665
666 int
667 hms_wait (status)
668 WAITTYPE *status;
669 {
670 /* Strings to look for. '?' means match any single character.
671 Note that with the algorithm we use, the initial character
672 of the string cannot recur in the string, or we will not
673 find some cases of the string in the input. */
674
675 static char bpt[] = "At breakpoint:";
676
677 /* It would be tempting to look for "\n[__exit + 0x8]\n"
678 but that requires loading symbols with "yc i" and even if
679 we did do that we don't know that the file has symbols. */
680 static char exitmsg[] = "HMS>";
681 char *bp = bpt;
682 char *ep = exitmsg;
683
684 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
685 char swallowed[50];
686
687 /* Current position in swallowed. */
688 char *swallowed_p = swallowed;
689
690 int ch;
691 int ch_handled;
692 int old_timeout = timeout;
693 int old_immediate_quit = immediate_quit;
694 int swallowed_cr = 0;
695
696 WSETEXIT ((*status), 0);
697
698 if (need_artificial_trap != 0)
699 {
700 WSETSTOP ((*status), SIGTRAP);
701 need_artificial_trap--;
702 return 0;
703 }
704
705 timeout = 99999; /* Don't time out -- user program is running. */
706 immediate_quit = 1; /* Helps ability to QUIT */
707 while (1)
708 {
709 QUIT; /* Let user quit and leave process running */
710 ch_handled = 0;
711 ch = readchar ();
712 if (ch == *bp)
713 {
714 bp++;
715 if (*bp == '\0')
716 break;
717 ch_handled = 1;
718
719 *swallowed_p++ = ch;
720 }
721 else
722 {
723 bp = bpt;
724 }
725 if (ch == *ep || *ep == '?')
726 {
727 ep++;
728 if (*ep == '\0')
729 break;
730
731 if (!ch_handled)
732 *swallowed_p++ = ch;
733 ch_handled = 1;
734 }
735 else
736 {
737 ep = exitmsg;
738 }
739
740 if (!ch_handled)
741 {
742 char *p;
743
744 /* Print out any characters which have been swallowed. */
745 for (p = swallowed; p < swallowed_p; ++p)
746 putc (*p, stdout);
747 swallowed_p = swallowed;
748
749 if ((ch != '\r' && ch != '\n') || swallowed_cr > 10)
750 {
751 putc (ch, stdout);
752 swallowed_cr = 10;
753 }
754 swallowed_cr++;
755
756 }
757 }
758 if (*bp == '\0')
759 {
760 WSETSTOP ((*status), SIGTRAP);
761 expect_prompt ();
762 }
763 else
764 {
765 WSETEXIT ((*status), 0);
766 }
767
768 timeout = old_timeout;
769 immediate_quit = old_immediate_quit;
770 return 0;
771 }
772
773 /* Return the name of register number REGNO
774 in the form input and output by hms.
775
776 Returns a pointer to a static buffer containing the answer. */
777 static char *
778 get_reg_name (regno)
779 int regno;
780 {
781 static char *rn[] = REGISTER_NAMES;
782
783 return rn[regno];
784 }
785
786 /* Read the remote registers. */
787 static int
788 gethex (length, start, ok)
789 unsigned int length;
790 char *start;
791 int *ok;
792 {
793 int result = 0;
794
795 while (length--)
796 {
797 result <<= 4;
798 if (*start >= 'a' && *start <= 'f')
799 {
800 result += *start - 'a' + 10;
801 }
802 else if (*start >= 'A' && *start <= 'F')
803 {
804 result += *start - 'A' + 10;
805 }
806 else if (*start >= '0' && *start <= '9')
807 {
808 result += *start - '0';
809 }
810 else
811 *ok = 0;
812 start++;
813
814 }
815 return result;
816 }
817 static int
818 timed_read (buf, n, timeout)
819 char *buf;
820
821 {
822 int i;
823 char c;
824
825 i = 0;
826 while (i < n)
827 {
828 c = readchar ();
829
830 if (c == 0)
831 return i;
832 buf[i] = c;
833 i++;
834
835 }
836 return i;
837 }
838
839 hms_write (a, l)
840 char *a;
841 {
842 int i;
843
844 SERIAL_WRITE (desc, a, l);
845
846 if (!quiet)
847 for (i = 0; i < l; i++)
848 {
849 printf ("%c", a[i]);
850 }
851 }
852
853 hms_write_cr (s)
854 char *s;
855 {
856 hms_write (s, strlen (s));
857 hms_write ("\r", 1);
858 }
859
860 static void
861 hms_fetch_register (dummy)
862 int dummy;
863 {
864 #define REGREPLY_SIZE 79
865 char linebuf[REGREPLY_SIZE + 1];
866 int i;
867 int s;
868 int gottok;
869
870 REGISTER_TYPE reg[NUM_REGS];
871 int foo[8];
872
873 check_open ();
874
875 do
876 {
877
878 hms_write_cr ("r");
879 s = timed_read (linebuf, REGREPLY_SIZE, 1);
880
881 linebuf[REGREPLY_SIZE] = 0;
882 gottok = 0;
883 if (linebuf[0] == 'r' &&
884 linebuf[3] == 'P' &&
885 linebuf[4] == 'C' &&
886 linebuf[5] == '=' &&
887 linebuf[75] == 'H' &&
888 linebuf[76] == 'M' &&
889 linebuf[77] == 'S')
890 {
891 /*
892 PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
893 5436789012345678901234567890123456789012345678901234567890123456789012
894 0 1 2 3 4 5 6
895 */
896 gottok = 1;
897
898 reg[PC_REGNUM] = gethex (4, linebuf + 6, &gottok);
899 reg[CCR_REGNUM] = gethex (2, linebuf + 15, &gottok);
900 for (i = 0; i < 8; i++)
901 {
902 reg[i] = gethex (4, linebuf + 34 + 5 * i, &gottok);
903 }
904 }
905 }
906 while (!gottok);
907 for (i = 0; i < NUM_REGS; i++)
908 {
909 char swapped[2];
910
911 swapped[1] = reg[i];
912 swapped[0] = (reg[i]) >> 8;
913
914 supply_register (i, swapped);
915 }
916 }
917
918 /* Store register REGNO, or all if REGNO == -1.
919 Return errno value. */
920 static void
921 hms_store_register (regno)
922 int regno;
923 {
924 if (regno == -1)
925 {
926 for (regno = 0; regno < NUM_REGS; regno++)
927 {
928 hms_store_register (regno);
929 }
930 }
931 else
932 {
933 char *name = get_reg_name (regno);
934 char buffer[100];
935
936 sprintf (buffer, "r %s=%x", name, read_register (regno));
937 hms_write_cr (buffer);
938 expect_prompt ();
939 }
940 }
941
942 /* Get ready to modify the registers array. On machines which store
943 individual registers, this doesn't need to do anything. On machines
944 which store all the registers in one fell swoop, this makes sure
945 that registers contains all the registers from the program being
946 debugged. */
947
948 void
949 hms_prepare_to_store ()
950 {
951 /* Do nothing, since we can store individual regs */
952 }
953
954 static CORE_ADDR
955 translate_addr (addr)
956 CORE_ADDR addr;
957 {
958
959 return (addr);
960
961 }
962
963 /* Read a word from remote address ADDR and return it.
964 * This goes through the data cache.
965 */
966 int
967 hms_fetch_word (addr)
968 CORE_ADDR addr;
969 {
970 return dcache_fetch (addr);
971 }
972
973 /* Write a word WORD into remote address ADDR.
974 This goes through the data cache. */
975
976 void
977 hms_store_word (addr, word)
978 CORE_ADDR addr;
979 int word;
980 {
981 dcache_poke (addr, word);
982 }
983
984 int
985 hms_xfer_inferior_memory (memaddr, myaddr, len, write, target)
986 CORE_ADDR memaddr;
987 char *myaddr;
988 int len;
989 int write;
990 struct target_ops *target; /* ignored */
991 {
992 register int i;
993
994 /* Round starting address down to longword boundary. */
995 register CORE_ADDR addr;
996
997 /* Round ending address up; get number of longwords that makes. */
998 register int count;
999
1000 /* Allocate buffer of that many longwords. */
1001 register int *buffer;
1002
1003 memaddr &= 0xffff;
1004 addr = memaddr & -sizeof (int);
1005 count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
1006
1007 buffer = (int *) alloca (count * sizeof (int));
1008
1009 if (write)
1010 {
1011 /* Fill start and end extra bytes of buffer with existing memory data. */
1012
1013 if (addr != memaddr || len < (int) sizeof (int))
1014 {
1015 /* Need part of initial word -- fetch it. */
1016 buffer[0] = hms_fetch_word (addr);
1017 }
1018
1019 if (count > 1) /* FIXME, avoid if even boundary */
1020 {
1021 buffer[count - 1]
1022 = hms_fetch_word (addr + (count - 1) * sizeof (int));
1023 }
1024
1025 /* Copy data to be written over corresponding part of buffer */
1026
1027 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
1028
1029 /* Write the entire buffer. */
1030
1031 for (i = 0; i < count; i++, addr += sizeof (int))
1032 {
1033 errno = 0;
1034 hms_store_word (addr, buffer[i]);
1035 if (errno)
1036 {
1037
1038 return 0;
1039 }
1040
1041 }
1042 }
1043 else
1044 {
1045 /* Read all the longwords */
1046 for (i = 0; i < count; i++, addr += sizeof (int))
1047 {
1048 errno = 0;
1049 buffer[i] = hms_fetch_word (addr);
1050 if (errno)
1051 {
1052 return 0;
1053 }
1054 QUIT;
1055 }
1056
1057 /* Copy appropriate bytes out of the buffer. */
1058 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
1059 }
1060
1061 return len;
1062 }
1063
1064 int
1065 hms_write_inferior_memory (memaddr, myaddr, len)
1066 CORE_ADDR memaddr;
1067 unsigned char *myaddr;
1068 int len;
1069 {
1070 bfd_vma addr;
1071 int done;
1072 int todo;
1073
1074 done = 0;
1075 while (done < len)
1076 {
1077 char buffer[20];
1078 int thisgo;
1079 int idx;
1080
1081 thisgo = len - done;
1082 if (thisgo > 20)
1083 thisgo = 20;
1084
1085 sprintf (buffer, "M.B %4x =", memaddr + done);
1086 hms_write (buffer, 10);
1087 for (idx = 0; idx < thisgo; idx++)
1088 {
1089 char buf[20];
1090
1091 sprintf (buf, "%2x ", myaddr[idx + done]);
1092 hms_write (buf, 3);
1093 }
1094 hms_write_cr ("");
1095 expect_prompt ();
1096 done += thisgo;
1097 }
1098
1099 }
1100
1101 void
1102 hms_files_info ()
1103 {
1104 char *file = "nothing";
1105
1106 if (exec_bfd)
1107 file = bfd_get_filename (exec_bfd);
1108
1109 if (exec_bfd)
1110 #ifdef __GO32__
1111 printf_filtered ("\tAttached to DOS asynctsr and running program %s\n", file);
1112 #else
1113 printf_filtered ("\tAttached to %s at %d baud and running program %s\n", dev_name, baudrate, file);
1114 #endif
1115 printf_filtered ("\ton an H8/300 processor.\n");
1116 }
1117
1118 /* Copy LEN bytes of data from debugger memory at MYADDR
1119 to inferior's memory at MEMADDR. Returns errno value.
1120 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1121 */
1122
1123 /* Read LEN bytes from inferior memory at MEMADDR. Put the result
1124 at debugger address MYADDR. Returns errno value. */
1125 int
1126 hms_read_inferior_memory (memaddr, myaddr, len)
1127 CORE_ADDR memaddr;
1128 char *myaddr;
1129 int len;
1130 {
1131 /* Align to nearest low 16 bits */
1132 int i;
1133
1134 #if 0
1135 CORE_ADDR start = memaddr & ~0xf;
1136 CORE_ADDR end = ((memaddr + len + 16) & ~0xf) - 1;
1137
1138 #endif
1139 CORE_ADDR start = memaddr;
1140 CORE_ADDR end = memaddr + len - 1;
1141
1142 int ok = 1;
1143
1144 /*
1145 AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1146 012345678901234567890123456789012345678901234567890123456789012345
1147 0 1 2 3 4 5 6
1148 */
1149 char buffer[66];
1150
1151 if (memaddr & 0xf)
1152 abort ();
1153 if (len != 16)
1154 abort ();
1155
1156 sprintf (buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
1157 hms_write_cr (buffer);
1158 /* drop the echo and newline*/
1159 for (i = 0; i < 13; i++)
1160 readchar ();
1161
1162 /* Grab the lines as they come out and fill the area */
1163 /* Skip over cr */
1164 while (1)
1165 {
1166 int p;
1167 int i;
1168 int addr;
1169 size_t idx;
1170
1171 char byte[16];
1172
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 for (p = 0; p < 16; p++)
1192 {
1193 if (addr + p >= memaddr &&
1194 addr + p < memaddr + len)
1195 {
1196 myaddr[(addr + p) - memaddr] = byte[p];
1197
1198 }
1199
1200 }
1201 }
1202 expect ("emory>");
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
1219 push_target (&hms_ops);
1220 }
1221
1222 #define MAX_BREAKS 16
1223 static int num_brkpts = 0;
1224 static int
1225 hms_insert_breakpoint (addr, save)
1226 CORE_ADDR addr;
1227 char *save; /* Throw away, let hms save instructions */
1228 {
1229 check_open ();
1230
1231 if (num_brkpts < MAX_BREAKS)
1232 {
1233 char buffer[100];
1234
1235 num_brkpts++;
1236 sprintf (buffer, "b %x", addr & 0xffff);
1237 hms_write_cr (buffer);
1238 expect_prompt ();
1239 return (0);
1240 }
1241 else
1242 {
1243 fprintf_filtered (stderr,
1244 "Too many break points, break point not installed\n");
1245 return (1);
1246 }
1247
1248 }
1249 static int
1250 hms_remove_breakpoint (addr, save)
1251 CORE_ADDR addr;
1252 char *save; /* Throw away, let hms save instructions */
1253 {
1254 if (num_brkpts > 0)
1255 {
1256 char buffer[100];
1257
1258 num_brkpts--;
1259 sprintf (buffer, "b - %x", addr & 0xffff);
1260 hms_write_cr (buffer);
1261 expect_prompt ();
1262
1263 }
1264 return (0);
1265 }
1266
1267 /* Clear the hmss notion of what the break points are */
1268 static int
1269 hms_clear_breakpoints ()
1270 {
1271
1272 if (is_open)
1273 {
1274 hms_write_cr ("b -");
1275 expect_prompt ();
1276 }
1277 num_brkpts = 0;
1278 }
1279 static void
1280 hms_mourn ()
1281 {
1282 hms_clear_breakpoints ();
1283 unpush_target (&hms_ops);
1284 generic_mourn_inferior ();
1285 }
1286
1287 /* Put a command string, in args, out to the hms. The hms is assumed to
1288 be in raw mode, all writing/reading done through desc.
1289 Ouput from the hms is placed on the users terminal until the
1290 prompt from the hms is seen.
1291 FIXME: Can't handle commands that take input. */
1292
1293 void
1294 hms_com (args, fromtty)
1295 char *args;
1296 int fromtty;
1297 {
1298 check_open ();
1299
1300 if (!args)
1301 return;
1302
1303 /* Clear all input so only command relative output is displayed */
1304
1305 hms_write_cr (args);
1306 hms_write ("\030", 1);
1307 expect_prompt ();
1308 }
1309
1310 /* Define the target subroutine names */
1311
1312 struct target_ops hms_ops =
1313 {
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 0, /* notice_signals */
1333 process_stratum, 0, /* next */
1334 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1335 0, 0, /* Section pointers */
1336 OPS_MAGIC, /* Always the last thing */
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 static
1359 hms_speed (s)
1360 char *s;
1361 {
1362 check_open ();
1363
1364 if (s)
1365 {
1366 char buffer[100];
1367 int newrate = atoi (s);
1368 int which = 0;
1369
1370 if (SERIAL_SETBAUDRATE (desc, newrate))
1371 error ("Can't use %d baud\n", newrate);
1372
1373 printf_filtered ("Checking target is in sync\n");
1374
1375 printf_filtered ("Sending commands to set target to %d\n",
1376 baudrate);
1377
1378 sprintf (buffer, "tm %d. N 8 1", baudrate);
1379 hms_write_cr (buffer);
1380 }
1381 }
1382
1383 /***********************************************************************/
1384
1385 void
1386 _initialize_remote_hms ()
1387 {
1388 add_target (&hms_ops);
1389
1390 add_com ("hms <command>", class_obscure, hms_com,
1391 "Send a command to the HMS monitor.");
1392 add_com ("snoop", class_obscure, hms_quiet,
1393 "Show what commands are going to the monitor");
1394
1395 add_com ("device", class_obscure, hms_device,
1396 "Set the terminal line for HMS communications");
1397
1398 add_com ("speed", class_obscure, hms_speed,
1399 "Set the terminal line speed for HMS communications");
1400
1401 dev_name = NULL;
1402 }
This page took 0.06023 seconds and 4 git commands to generate.