* configure.in: Match z8k-*-sim for z8000.
[deliverable/binutils-gdb.git] / gdb / remote-hms.c
... / ...
CommitLineData
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
6This file is part of GDB.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, 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 */
37extern int stop_soon_quietly; /* for wait_for_inferior */
38
39/* Forward data declarations */
40extern struct target_ops hms_ops; /* Forward declaration */
41
42/* Forward function declarations */
43static void hms_fetch_registers ();
44static int hms_store_registers ();
45static void hms_close ();
46static int hms_clear_breakpoints ();
47
48extern struct target_ops hms_ops;
49
50static 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)
66struct 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
73struct dcache_block dcache_free, dcache_valid;
74
75/* Free all the data cache blocks, thus discarding all cached data. */
76static
77void
78dcache_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 */
93static
94struct dcache_block *
95dcache_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. */
115static
116int
117dcache_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...). */
132static
133struct dcache_block *
134dcache_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. */
154static
155int
156dcache_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. */
176static void
177dcache_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. */
206struct dcache_block the_cache[DCACHE_SIZE];
207
208/* Initialize the data cache. */
209static void
210dcache_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
226static int timeout = 2;
227
228static 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
234int is_open = 0;
235int
236check_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. */
249static int
250readchar ()
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
265static int
266readchar_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. */
282static void
283expect (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. */
319static void
320expect_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). */
327static int
328get_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. */
354static void
355get_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 */
366static long
367get_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
384static int need_artificial_trap = 0;
385
386void
387hms_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 */
397static void
398hms_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. */
459void
460hms_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
492static char *
493find_end_of_word (s)
494 char *s;
495{
496 while (*s && !isspace (*s))
497 s++;
498 return s;
499}
500
501static char *
502get_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
530static int baudrate = 9600;
531
532static int
533is_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}
557static void
558set_rate ()
559{
560 if (!serial_setbaudrate (baudrate))
561 error ("Can't set baudrate");
562}
563
564static void
565get_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
583static void
584hms_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
621static void
622hms_close (quitting)
623 int quitting;
624{
625 /* Clear any break points */
626 hms_clear_breakpoints ();
627 sleep (1); /* Let any output make it all the way back */
628 if (is_open) {
629 serial_write ("R\r", 2);
630 serial_close ();
631 }
632 is_open = 0;
633}
634
635/* Terminate the open connection to the remote debugger.
636 Use this when you want to detach and do something else
637 with your gdb. */
638void
639hms_detach (args, from_tty)
640 char *args;
641 int from_tty;
642{
643 if (is_open)
644 {
645 hms_clear_breakpoints ();
646 }
647
648 pop_target (); /* calls hms_close to do the real work */
649 if (from_tty)
650 printf_filtered ("Ending remote %s debugging\n", target_shortname);
651}
652
653/* Tell the remote machine to resume. */
654
655void
656hms_resume (step, sig)
657 int step, sig;
658{
659 dcache_flush ();
660
661 if (step)
662 {
663 hms_write_cr ("s");
664 expect ("Step>");
665
666 /* Force the next hms_wait to return a trap. Not doing anything
667 about I/O from the target means that the user has to type
668 "continue" to see any. FIXME, this should be fixed. */
669 need_artificial_trap = 1;
670 }
671 else
672 {
673 hms_write_cr ("g");
674 expect ("g");
675 }
676}
677
678/* Wait until the remote machine stops, then return,
679 storing status in STATUS just as `wait' would. */
680
681int
682hms_wait (status)
683 WAITTYPE *status;
684{
685 /* Strings to look for. '?' means match any single character.
686 Note that with the algorithm we use, the initial character
687 of the string cannot recur in the string, or we will not
688 find some cases of the string in the input. */
689
690 static char bpt[] = "At breakpoint:";
691
692 /* It would be tempting to look for "\n[__exit + 0x8]\n"
693 but that requires loading symbols with "yc i" and even if
694 we did do that we don't know that the file has symbols. */
695 static char exitmsg[] = "HMS>";
696 char *bp = bpt;
697 char *ep = exitmsg;
698
699 /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
700 char swallowed[50];
701
702 /* Current position in swallowed. */
703 char *swallowed_p = swallowed;
704
705 int ch;
706 int ch_handled;
707 int old_timeout = timeout;
708 int old_immediate_quit = immediate_quit;
709 int swallowed_cr = 0;
710
711 WSETEXIT ((*status), 0);
712
713 if (need_artificial_trap != 0)
714 {
715 WSETSTOP ((*status), SIGTRAP);
716 need_artificial_trap--;
717 return 0;
718 }
719
720 timeout = 99999; /* Don't time out -- user program is running. */
721 immediate_quit = 1; /* Helps ability to QUIT */
722 while (1)
723 {
724 QUIT; /* Let user quit and leave process running */
725 ch_handled = 0;
726 ch = readchar ();
727 if (ch == *bp)
728 {
729 bp++;
730 if (*bp == '\0')
731 break;
732 ch_handled = 1;
733
734 *swallowed_p++ = ch;
735 }
736 else
737 {
738 bp = bpt;
739 }
740 if (ch == *ep || *ep == '?')
741 {
742 ep++;
743 if (*ep == '\0')
744 break;
745
746 if (!ch_handled)
747 *swallowed_p++ = ch;
748 ch_handled = 1;
749 }
750 else
751 {
752 ep = exitmsg;
753 }
754
755 if (!ch_handled)
756 {
757 char *p;
758
759 /* Print out any characters which have been swallowed. */
760 for (p = swallowed; p < swallowed_p; ++p)
761 putc (*p, stdout);
762 swallowed_p = swallowed;
763
764 if ((ch != '\r' && ch != '\n') || swallowed_cr > 10)
765 {
766 putc (ch, stdout);
767 swallowed_cr = 10;
768 }
769 swallowed_cr++;
770
771 }
772 }
773 if (*bp == '\0')
774 {
775 WSETSTOP ((*status), SIGTRAP);
776 expect_prompt ();
777 }
778 else
779 {
780 WSETEXIT ((*status), 0);
781 }
782
783 timeout = old_timeout;
784 immediate_quit = old_immediate_quit;
785 return 0;
786}
787
788/* Return the name of register number REGNO
789 in the form input and output by hms.
790
791 Returns a pointer to a static buffer containing the answer. */
792static char *
793get_reg_name (regno)
794 int regno;
795{
796 static char *rn[] = REGISTER_NAMES;
797
798 return rn[regno];
799}
800
801/* Read the remote registers. */
802static int
803gethex (length, start, ok)
804 unsigned int length;
805 char *start;
806 int *ok;
807{
808 int result = 0;
809
810 while (length--)
811 {
812 result <<= 4;
813 if (*start >= 'a' && *start <= 'f')
814 {
815 result += *start - 'a' + 10;
816 }
817 else if (*start >= 'A' && *start <= 'F')
818 {
819 result += *start - 'A' + 10;
820 }
821 else if (*start >= '0' && *start <= '9')
822 {
823 result += *start - '0';
824 }
825 else
826 *ok = 0;
827 start++;
828
829 }
830 return result;
831}
832static int
833timed_read (buf, n, timeout)
834 char *buf;
835
836{
837 int i;
838 char c;
839
840 i = 0;
841 while (i < n)
842 {
843 c = readchar ();
844
845 if (c == 0)
846 return i;
847 buf[i] = c;
848 i++;
849
850 }
851 return i;
852
853}
854
855hms_write (a, l)
856 char *a;
857{
858 int i;
859
860 serial_write (a, l);
861
862 if (!quiet)
863 for (i = 0; i < l; i++)
864 {
865 printf ("%c", a[i]);
866 }
867}
868
869hms_write_cr (s)
870 char *s;
871{
872 hms_write (s, strlen (s));
873 hms_write ("\r", 1);
874}
875
876static void
877hms_fetch_register (dummy)
878 int dummy;
879{
880#define REGREPLY_SIZE 79
881 char linebuf[REGREPLY_SIZE + 1];
882 int i;
883 int s;
884 int gottok;
885
886 REGISTER_TYPE reg[NUM_REGS];
887 int foo[8];
888
889 check_open ();
890
891 do
892 {
893
894 hms_write_cr ("r");
895 s = timed_read (linebuf, REGREPLY_SIZE, 1);
896
897 linebuf[REGREPLY_SIZE] = 0;
898 gottok = 0;
899 if (linebuf[0] == 'r' &&
900 linebuf[3] == 'P' &&
901 linebuf[4] == 'C' &&
902 linebuf[5] == '=' &&
903 linebuf[75] == 'H' &&
904 linebuf[76] == 'M' &&
905 linebuf[77] == 'S')
906 {
907 /*
908 PC=XXXX CCR=XX:XXXXXXXX R0-R7= XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
909 5436789012345678901234567890123456789012345678901234567890123456789012
910 0 1 2 3 4 5 6
911 */
912 gottok = 1;
913
914 reg[PC_REGNUM] = gethex (4, linebuf + 6, &gottok);
915 reg[CCR_REGNUM] = gethex (2, linebuf + 15, &gottok);
916 for (i = 0; i < 8; i++)
917 {
918 reg[i] = gethex (4, linebuf + 34 + 5 * i, &gottok);
919 }
920 }
921 }
922 while (!gottok);
923 for (i = 0; i < NUM_REGS; i++)
924 {
925 char swapped[2];
926
927 swapped[1] = reg[i];
928 swapped[0] = (reg[i]) >> 8;
929
930 supply_register (i, swapped);
931 }
932}
933
934/* Store register REGNO, or all if REGNO == -1.
935 Return errno value. */
936static void
937hms_store_register (regno)
938 int regno;
939{
940
941 /* printf("hms_store_register() called.\n"); fflush(stdout); /* */
942 if (regno == -1)
943 {
944 for (regno = 0; regno < NUM_REGS; regno++)
945 {
946 hms_store_register (regno);
947 }
948 }
949 else
950 {
951 char *name = get_reg_name (regno);
952 char buffer[100];
953
954 sprintf (buffer, "r %s=%x", name, read_register (regno));
955 hms_write_cr (buffer);
956 expect_prompt ();
957 }
958}
959
960/* Get ready to modify the registers array. On machines which store
961 individual registers, this doesn't need to do anything. On machines
962 which store all the registers in one fell swoop, this makes sure
963 that registers contains all the registers from the program being
964 debugged. */
965
966void
967hms_prepare_to_store ()
968{
969 /* Do nothing, since we can store individual regs */
970}
971
972static CORE_ADDR
973translate_addr (addr)
974 CORE_ADDR addr;
975{
976
977 return (addr);
978
979}
980
981/* Read a word from remote address ADDR and return it.
982 * This goes through the data cache.
983 */
984int
985hms_fetch_word (addr)
986 CORE_ADDR addr;
987{
988 return dcache_fetch (addr);
989}
990
991/* Write a word WORD into remote address ADDR.
992 This goes through the data cache. */
993
994void
995hms_store_word (addr, word)
996 CORE_ADDR addr;
997 int word;
998{
999 dcache_poke (addr, word);
1000}
1001
1002int
1003hms_xfer_inferior_memory (memaddr, myaddr, len, write, target)
1004 CORE_ADDR memaddr;
1005 char *myaddr;
1006 int len;
1007 int write;
1008 struct target_ops *target; /* ignored */
1009{
1010 register int i;
1011
1012 /* Round starting address down to longword boundary. */
1013 register CORE_ADDR addr;
1014
1015 /* Round ending address up; get number of longwords that makes. */
1016 register int count;
1017
1018 /* Allocate buffer of that many longwords. */
1019 register int *buffer;
1020
1021 memaddr &= 0xffff;
1022 addr = memaddr & -sizeof (int);
1023 count = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
1024
1025 buffer = (int *) alloca (count * sizeof (int));
1026
1027 if (write)
1028 {
1029 /* Fill start and end extra bytes of buffer with existing memory data. */
1030
1031 if (addr != memaddr || len < (int) sizeof (int))
1032 {
1033 /* Need part of initial word -- fetch it. */
1034 buffer[0] = hms_fetch_word (addr);
1035 }
1036
1037 if (count > 1) /* FIXME, avoid if even boundary */
1038 {
1039 buffer[count - 1]
1040 = hms_fetch_word (addr + (count - 1) * sizeof (int));
1041 }
1042
1043 /* Copy data to be written over corresponding part of buffer */
1044
1045 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
1046
1047 /* Write the entire buffer. */
1048
1049 for (i = 0; i < count; i++, addr += sizeof (int))
1050 {
1051 errno = 0;
1052 hms_store_word (addr, buffer[i]);
1053 if (errno)
1054 {
1055
1056 return 0;
1057 }
1058
1059 }
1060 }
1061 else
1062 {
1063 /* Read all the longwords */
1064 for (i = 0; i < count; i++, addr += sizeof (int))
1065 {
1066 errno = 0;
1067 buffer[i] = hms_fetch_word (addr);
1068 if (errno)
1069 {
1070 return 0;
1071 }
1072 QUIT;
1073 }
1074
1075 /* Copy appropriate bytes out of the buffer. */
1076 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
1077 }
1078
1079 return len;
1080}
1081
1082int
1083hms_write_inferior_memory (memaddr, myaddr, len)
1084 CORE_ADDR memaddr;
1085 unsigned char *myaddr;
1086 int len;
1087{
1088 bfd_vma addr;
1089 int done;
1090 int todo;
1091
1092 done = 0;
1093 while (done < len)
1094 {
1095 char buffer[20];
1096 int thisgo;
1097 int idx;
1098
1099 thisgo = len - done;
1100 if (thisgo > 20)
1101 thisgo = 20;
1102
1103 sprintf (buffer, "M.B %4x =", memaddr + done);
1104 hms_write (buffer, 10);
1105 for (idx = 0; idx < thisgo; idx++)
1106 {
1107 char buf[20];
1108
1109 sprintf (buf, "%2x ", myaddr[idx + done]);
1110 hms_write (buf, 3);
1111 }
1112 hms_write_cr ("");
1113 expect_prompt ();
1114 done += thisgo;
1115 }
1116
1117}
1118
1119void
1120hms_files_info ()
1121{
1122 char *file = "nothing";
1123
1124 if (exec_bfd)
1125 file = bfd_get_filename (exec_bfd);
1126
1127 if (exec_bfd)
1128#ifdef __GO32__
1129 printf_filtered ("\tAttached to DOS asynctsr and running program %s\n", file);
1130#else
1131 printf_filtered ("\tAttached to %s at %d baud and running program %s\n", file);
1132#endif
1133 printf_filtered ("\ton an H8/300 processor.\n");
1134}
1135
1136/* Copy LEN bytes of data from debugger memory at MYADDR
1137 to inferior's memory at MEMADDR. Returns errno value.
1138 * sb/sh instructions don't work on unaligned addresses, when TU=1.
1139 */
1140
1141/* Read LEN bytes from inferior memory at MEMADDR. Put the result
1142 at debugger address MYADDR. Returns errno value. */
1143int
1144hms_read_inferior_memory (memaddr, myaddr, len)
1145 CORE_ADDR memaddr;
1146 char *myaddr;
1147 int len;
1148{
1149 /* Align to nearest low 16 bits */
1150 int i;
1151
1152#if 0
1153 CORE_ADDR start = memaddr & ~0xf;
1154 CORE_ADDR end = ((memaddr + len + 16) & ~0xf) - 1;
1155
1156#endif
1157 CORE_ADDR start = memaddr;
1158 CORE_ADDR end = memaddr + len - 1;
1159
1160 int ok = 1;
1161
1162 /*
1163 AAAA: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX '................'
1164 012345678901234567890123456789012345678901234567890123456789012345
1165 0 1 2 3 4 5 6
1166 */
1167 char buffer[66];
1168
1169 if (memaddr & 0xf)
1170 abort ();
1171 if (len != 16)
1172 abort ();
1173
1174 sprintf (buffer, "m %4x %4x", start & 0xffff, end & 0xffff);
1175 hms_write_cr (buffer);
1176 /* drop the echo and newline*/
1177 for (i = 0; i < 13; i++)
1178 readchar ();
1179
1180 /* Grab the lines as they come out and fill the area */
1181 /* Skip over cr */
1182 while (1)
1183 {
1184 int p;
1185 int i;
1186 int addr;
1187 size_t idx;
1188
1189 char byte[16];
1190
1191 buffer[0] = readchar ();
1192 if (buffer[0] == 'M')
1193 break;
1194 for (i = 1; i < 66; i++)
1195 buffer[i] = readchar ();
1196
1197 /* Now parse the line */
1198
1199 addr = gethex (4, buffer, &ok);
1200 idx = 6;
1201 for (p = 0; p < 16; p += 2)
1202 {
1203 byte[p] = gethex (2, buffer + idx, &ok);
1204 byte[p + 1] = gethex (2, buffer + idx + 2, &ok);
1205 idx += 5;
1206
1207 }
1208
1209 for (p = 0; p < 16; p++)
1210 {
1211 if (addr + p >= memaddr &&
1212 addr + p < memaddr + len)
1213 {
1214 myaddr[(addr + p) - memaddr] = byte[p];
1215
1216 }
1217
1218 }
1219 }
1220 expect("emory>");
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
1231hms_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
1242static int num_brkpts = 0;
1243static int
1244hms_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}
1268static int
1269hms_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 */
1287static int
1288hms_clear_breakpoints ()
1289{
1290
1291 if (is_open)
1292 {
1293 hms_write_cr ("b -");
1294 expect_prompt ();
1295 }
1296 num_brkpts = 0;
1297}
1298static void
1299hms_mourn ()
1300{
1301 hms_clear_breakpoints ();
1302 unpush_target (&hms_ops);
1303 generic_mourn_inferior ();
1304}
1305
1306/* Put a command string, in args, out to the hms. The hms is assumed to
1307 be in raw mode, all writing/reading done through desc.
1308 Ouput from the hms is placed on the users terminal until the
1309 prompt from the hms is seen.
1310 FIXME: Can't handle commands that take input. */
1311
1312void
1313hms_com (args, fromtty)
1314 char *args;
1315 int fromtty;
1316{
1317 check_open ();
1318
1319 if (!args)
1320 return;
1321
1322 /* Clear all input so only command relative output is displayed */
1323
1324 hms_write_cr (args);
1325 hms_write ("\030", 1);
1326 expect_prompt ();
1327}
1328
1329/* Define the target subroutine names */
1330
1331struct target_ops hms_ops =
1332{
1333 "hms", "Remote HMS monitor",
1334 "Use the H8 evaluation board running the HMS monitor connected\n\
1335by a serial line.",
1336
1337 hms_open, hms_close,
1338 0, hms_detach, hms_resume, hms_wait, /* attach */
1339 hms_fetch_register, hms_store_register,
1340 hms_prepare_to_store,
1341 hms_xfer_inferior_memory,
1342 hms_files_info,
1343 hms_insert_breakpoint, hms_remove_breakpoint, /* Breakpoints */
1344 0, 0, 0, 0, 0, /* Terminal handling */
1345 hms_kill, /* FIXME, kill */
1346 hms_load,
1347 0, /* lookup_symbol */
1348 hms_create_inferior, /* create_inferior */
1349 hms_mourn, /* mourn_inferior FIXME */
1350 0, /* can_run */
1351 0, /* notice_signals */
1352 process_stratum, 0, /* next */
1353 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
1354 0, 0, /* Section pointers */
1355 OPS_MAGIC, /* Always the last thing */
1356};
1357
1358hms_quiet ()
1359{
1360 quiet = !quiet;
1361 if (quiet)
1362 printf_filtered ("Snoop disabled\n");
1363 else
1364 printf_filtered ("Snoop enabled\n");
1365
1366}
1367
1368hms_device (s)
1369 char *s;
1370{
1371 if (s)
1372 {
1373 dev_name = get_word (&s);
1374 }
1375}
1376
1377static
1378hms_speed (s)
1379 char *s;
1380{
1381 check_open ();
1382
1383 if (s)
1384 {
1385 char buffer[100];
1386 int newrate = atoi (s);
1387 int which = 0;
1388
1389 if (!serial_setbaudrate (newrate))
1390 error ("Can't use %d baud\n", newrate);
1391
1392 printf_filtered ("Checking target is in sync\n");
1393
1394 get_baudrate_right ();
1395 baudrate = newrate;
1396 printf_filtered ("Sending commands to set target to %d\n",
1397 baudrate);
1398
1399 sprintf (buffer, "tm %d. N 8 1", baudrate);
1400 hms_write_cr (buffer);
1401 }
1402}
1403
1404/***********************************************************************/
1405
1406void
1407_initialize_remote_hms ()
1408{
1409 add_target (&hms_ops);
1410
1411 add_com ("hms <command>", class_obscure, hms_com,
1412 "Send a command to the HMS monitor.");
1413 add_com ("snoop", class_obscure, hms_quiet,
1414 "Show what commands are going to the monitor");
1415
1416 add_com ("device", class_obscure, hms_device,
1417 "Set the terminal line for HMS communications");
1418
1419 add_com ("speed", class_obscure, hms_speed,
1420 "Set the terminal line speed for HMS communications");
1421
1422 dev_name = NULL;
1423}
This page took 0.026326 seconds and 4 git commands to generate.