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