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