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