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