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