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