2002-04-24 Pierre Muller <ics.u-strasbg.fr>
[deliverable/binutils-gdb.git] / gdb / remote-os9k.c
CommitLineData
c906108c 1/* Remote debugging interface for boot monitors, for GDB.
0a65a603
AC
2
3 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999,
4 2000, 2001, 2002 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
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.
c906108c 12
c5aa993b
JM
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.
c906108c 17
c5aa993b
JM
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., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
c906108c
SS
22
23/* This file was derived from remote-eb.c, which did a similar job, but for
24 an AMD-29K running EBMON. That file was in turn derived from remote.c
25 as mentioned in the following comment (left in for comic relief):
26
c5aa993b 27 "This is like remote.c but is for a different situation--
c906108c
SS
28 having a PC running os9000 hook up with a unix machine with
29 a serial line, and running ctty com2 on the PC. os9000 has a debug
30 monitor called ROMBUG running. Not to mention that the PC
31 has PC/NFS, so it can access the same executables that gdb can,
32 over the net in real time."
33
34 In reality, this module talks to a debug monitor called 'ROMBUG', which
35 We communicate with ROMBUG via a direct serial line, the network version
36 of ROMBUG is not available yet.
c5aa993b 37 */
c906108c
SS
38
39/* FIXME This file needs to be rewritten if it's to work again, either
40 to self-contained or to use the new monitor interface. */
41
42#include "defs.h"
43#include "gdbcore.h"
44#include "target.h"
43ff13b4 45#include "gdb_string.h"
9846de1b 46#include <sys/types.h>
c906108c
SS
47#include "command.h"
48#include "serial.h"
49#include "monitor.h"
50#include "remote-utils.h"
51#include "symtab.h"
52#include "symfile.h"
53#include "objfiles.h"
54#include "gdb-stabs.h"
4e052eda 55#include "regcache.h"
c906108c
SS
56
57struct cmd_list_element *showlist;
c5aa993b
JM
58extern struct target_ops rombug_ops; /* Forward declaration */
59extern struct monitor_ops rombug_cmds; /* Forward declaration */
c906108c
SS
60extern struct cmd_list_element *setlist;
61extern struct cmd_list_element *unsetlist;
62extern int attach_flag;
63
c5aa993b
JM
64static void rombug_close ();
65static void rombug_fetch_register ();
66static void rombug_fetch_registers ();
67static void rombug_store_register ();
c906108c 68#if 0
c5aa993b 69static int sr_get_debug (); /* flag set by "set remotedebug" */
c906108c 70#endif
c5aa993b 71static int hashmark; /* flag set by "set hash" */
c906108c
SS
72static int rombug_is_open = 0;
73
74/* FIXME: Replace with sr_get_debug (). */
75#define LOG_FILE "monitor.log"
76FILE *log_file;
77static int monitor_log = 0;
78static int tty_xon = 0;
79static int tty_xoff = 0;
80
81static int timeout = 10;
82static int is_trace_mode = 0;
c5aa993b 83/* Descriptor for I/O to remote machine. Initialize it to NULL */
819cc324 84static struct serial *monitor_desc = NULL;
c906108c
SS
85
86static CORE_ADDR bufaddr = 0;
87static int buflen = 0;
88static char readbuf[16];
89
90/* Send data to monitor. Works just like printf. */
91static void
c5aa993b 92printf_monitor (char *pattern,...)
c906108c
SS
93{
94 va_list args;
95 char buf[200];
96 int i;
97
c906108c 98 va_start (args, pattern);
c906108c 99
c5aa993b
JM
100 vsprintf (buf, pattern, args);
101 va_end (args);
c906108c 102
2cd58942 103 if (serial_write (monitor_desc, buf, strlen (buf)))
f8d17dc5
PM
104 fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n",
105 safe_strerror (errno));
c906108c
SS
106}
107
c5aa993b 108/* Read a character from the remote system, doing all the fancy timeout stuff */
c906108c 109static int
fba45db2 110readchar (int timeout)
c906108c
SS
111{
112 int c;
113
2cd58942 114 c = serial_readchar (monitor_desc, timeout);
c906108c 115
c5aa993b
JM
116 if (sr_get_debug ())
117 putchar (c & 0x7f);
c906108c 118
c5aa993b
JM
119 if (monitor_log && isascii (c))
120 putc (c & 0x7f, log_file);
c906108c
SS
121
122 if (c >= 0)
123 return c & 0x7f;
124
125 if (c == SERIAL_TIMEOUT)
126 {
127 if (timeout == 0)
128 return c; /* Polls shouldn't generate timeout errors */
129
c5aa993b 130 error ("Timeout reading from remote system.");
c906108c
SS
131 }
132
c5aa993b 133 perror_with_name ("remote-monitor");
c906108c
SS
134}
135
136/* Scan input from the remote system, until STRING is found. If DISCARD is
137 non-zero, then discard non-matching input, else print it out.
138 Let the user break out immediately. */
139static void
fba45db2 140expect (char *string, int discard)
c906108c
SS
141{
142 char *p = string;
143 int c;
144
c5aa993b 145 if (sr_get_debug ())
c906108c
SS
146 printf ("Expecting \"%s\"\n", string);
147
8edbea78 148 immediate_quit++;
c906108c
SS
149 while (1)
150 {
c5aa993b 151 c = readchar (timeout);
c906108c
SS
152 if (!isascii (c))
153 continue;
154 if (c == *p++)
155 {
156 if (*p == '\0')
157 {
8edbea78 158 immediate_quit--;
c5aa993b 159 if (sr_get_debug ())
c906108c
SS
160 printf ("\nMatched\n");
161 return;
162 }
163 }
164 else
165 {
166 if (!discard)
167 {
c5aa993b
JM
168 fwrite (string, 1, (p - 1) - string, stdout);
169 putchar ((char) c);
170 fflush (stdout);
c906108c
SS
171 }
172 p = string;
173 }
174 }
175}
176
177/* Keep discarding input until we see the ROMBUG prompt.
178
179 The convention for dealing with the prompt is that you
180 o give your command
181 o *then* wait for the prompt.
182
183 Thus the last thing that a procedure does with the serial line
184 will be an expect_prompt(). Exception: rombug_resume does not
185 wait for the prompt, because the terminal is being handed over
186 to the inferior. However, the next thing which happens after that
187 is a rombug_wait which does wait for the prompt.
188 Note that this includes abnormal exit, e.g. error(). This is
189 necessary to prevent getting into states from which we can't
190 recover. */
191static void
fba45db2 192expect_prompt (int discard)
c906108c
SS
193{
194 if (monitor_log)
c5aa993b
JM
195 /* This is a convenient place to do this. The idea is to do it often
196 enough that we never lose much data if we terminate abnormally. */
197 fflush (log_file);
198
199 if (is_trace_mode)
200 {
201 expect ("trace", discard);
202 }
203 else
204 {
205 expect (PROMPT, discard);
206 }
c906108c
SS
207}
208
209/* Get a hex digit from the remote system & return its value.
210 If ignore_space is nonzero, ignore spaces (not newline, tab, etc). */
211static int
fba45db2 212get_hex_digit (int ignore_space)
c906108c
SS
213{
214 int ch;
215 while (1)
216 {
c5aa993b 217 ch = readchar (timeout);
c906108c
SS
218 if (ch >= '0' && ch <= '9')
219 return ch - '0';
220 else if (ch >= 'A' && ch <= 'F')
221 return ch - 'A' + 10;
222 else if (ch >= 'a' && ch <= 'f')
223 return ch - 'a' + 10;
224 else if (ch == ' ' && ignore_space)
225 ;
226 else
227 {
c5aa993b
JM
228 expect_prompt (1);
229 error ("Invalid hex digit from remote system.");
c906108c
SS
230 }
231 }
232}
233
234/* Get a byte from monitor and put it in *BYT. Accept any number
235 leading spaces. */
236static void
fba45db2 237get_hex_byte (char *byt)
c906108c
SS
238{
239 int val;
240
241 val = get_hex_digit (1) << 4;
242 val |= get_hex_digit (0);
243 *byt = val;
244}
245
246/* Get N 32-bit words from remote, each preceded by a space,
247 and put them in registers starting at REGNO. */
248static void
fba45db2 249get_hex_regs (int n, int regno)
c906108c
SS
250{
251 long val;
252 int i;
253 unsigned char b;
254
255 for (i = 0; i < n; i++)
256 {
257 int j;
c5aa993b 258
c906108c
SS
259 val = 0;
260 for (j = 0; j < 4; j++)
261 {
262 get_hex_byte (&b);
d7449b42 263 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
c906108c
SS
264 val = (val << 8) + b;
265 else
c5aa993b 266 val = val + (b << (j * 8));
c906108c
SS
267 }
268 supply_register (regno++, (char *) &val);
269 }
270}
271
272/* This is called not only when we first attach, but also when the
273 user types "run" after having attached. */
274static void
fba45db2 275rombug_create_inferior (char *execfile, char *args, char **env)
c906108c
SS
276{
277 int entry_pt;
278
279 if (args && *args)
c5aa993b 280 error ("Can't pass arguments to remote ROMBUG process");
c906108c
SS
281
282 if (execfile == 0 || exec_bfd == 0)
c5aa993b 283 error ("No executable file specified");
c906108c
SS
284
285 entry_pt = (int) bfd_get_start_address (exec_bfd);
286
287 if (monitor_log)
288 fputs ("\nIn Create_inferior()", log_file);
289
290
291/* The "process" (board) is already stopped awaiting our commands, and
292 the program is already downloaded. We just set its PC and go. */
293
294 init_wait_for_inferior ();
c5aa993b 295 proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
c906108c
SS
296}
297
298/* Open a connection to a remote debugger.
299 NAME is the filename used for communication. */
300
301static char dev_name[100];
302
303static void
fba45db2 304rombug_open (char *args, int from_tty)
c906108c
SS
305{
306 if (args == NULL)
307 error ("Use `target RomBug DEVICE-NAME' to use a serial port, or \n\
308`target RomBug HOST-NAME:PORT-NUMBER' to use a network connection.");
309
c5aa993b 310 target_preopen (from_tty);
c906108c
SS
311
312 if (rombug_is_open)
c5aa993b 313 unpush_target (&rombug_ops);
c906108c 314
c5aa993b 315 strcpy (dev_name, args);
2cd58942 316 monitor_desc = serial_open (dev_name);
c906108c 317 if (monitor_desc == NULL)
c5aa993b 318 perror_with_name (dev_name);
c906108c
SS
319
320 /* if baud rate is set by 'set remotebaud' */
2cd58942 321 if (serial_setbaudrate (monitor_desc, sr_get_baud_rate ()))
c906108c 322 {
2cd58942 323 serial_close (monitor_desc);
c906108c
SS
324 perror_with_name ("RomBug");
325 }
2cd58942 326 serial_raw (monitor_desc);
c906108c
SS
327 if (tty_xon || tty_xoff)
328 {
c5aa993b
JM
329 struct hardware_ttystate
330 {
331 struct termios t;
332 }
333 *tty_s;
334
2cd58942 335 tty_s = (struct hardware_ttystate *) serial_get_tty_state (monitor_desc);
c5aa993b
JM
336 if (tty_xon)
337 tty_s->t.c_iflag |= IXON;
338 if (tty_xoff)
339 tty_s->t.c_iflag |= IXOFF;
2cd58942 340 serial_set_tty_state (monitor_desc, (serial_ttystate) tty_s);
c906108c
SS
341 }
342
343 rombug_is_open = 1;
344
345 log_file = fopen (LOG_FILE, "w");
346 if (log_file == NULL)
347 perror_with_name (LOG_FILE);
348
349 push_monitor (&rombug_cmds);
c5aa993b
JM
350 printf_monitor ("\r"); /* CR wakes up monitor */
351 expect_prompt (1);
c906108c
SS
352 push_target (&rombug_ops);
353 attach_flag = 1;
354
355 if (from_tty)
c5aa993b
JM
356 printf ("Remote %s connected to %s\n", target_shortname,
357 dev_name);
c906108c 358
c5aa993b 359 rombug_fetch_registers ();
c906108c
SS
360
361 printf_monitor ("ov e \r");
c5aa993b 362 expect_prompt (1);
c906108c
SS
363 bufaddr = 0;
364 buflen = 0;
365}
366
367/*
368 * Close out all files and local state before this target loses control.
369 */
370
371static void
fba45db2 372rombug_close (int quitting)
c906108c 373{
c5aa993b
JM
374 if (rombug_is_open)
375 {
2cd58942 376 serial_close (monitor_desc);
c5aa993b
JM
377 monitor_desc = NULL;
378 rombug_is_open = 0;
379 }
380
381 if (log_file)
382 {
383 if (ferror (log_file))
f8d17dc5 384 fprintf_unfiltered (gdb_stderr, "Error writing log file.\n");
c5aa993b 385 if (fclose (log_file) != 0)
f8d17dc5 386 fprintf_unfiltered (gdb_stderr, "Error closing log file.\n");
c5aa993b
JM
387 log_file = 0;
388 }
c906108c
SS
389}
390
391int
fba45db2 392rombug_link (char *mod_name, CORE_ADDR *text_reloc)
c906108c
SS
393{
394 int i, j;
395 unsigned long val;
396 unsigned char b;
397
c5aa993b
JM
398 printf_monitor ("l %s \r", mod_name);
399 expect_prompt (1);
400 printf_monitor (".r \r");
401 expect (REG_DELIM, 1);
402 for (i = 0; i <= 7; i++)
c906108c
SS
403 {
404 val = 0;
405 for (j = 0; j < 4; j++)
c5aa993b
JM
406 {
407 get_hex_byte (&b);
408 val = (val << 8) + b;
c906108c
SS
409 }
410 }
c5aa993b 411 expect_prompt (1);
c906108c
SS
412 *text_reloc = val;
413 return 1;
414}
415
416/* Terminate the open connection to the remote debugger.
417 Use this when you want to detach and do something else
418 with your gdb. */
419static void
fba45db2 420rombug_detach (int from_tty)
c906108c 421{
c5aa993b
JM
422 if (attach_flag)
423 {
424 printf_monitor (GO_CMD);
425 attach_flag = 0;
426 }
427 pop_target (); /* calls rombug_close to do the real work */
c906108c
SS
428 if (from_tty)
429 printf ("Ending remote %s debugging\n", target_shortname);
430}
c5aa993b 431
c906108c
SS
432/*
433 * Tell the remote machine to resume.
434 */
435static void
39f77062 436rombug_resume (ptid_t ptid, int step, enum target_signal sig)
c906108c
SS
437{
438 if (monitor_log)
439 fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
440
441 if (step)
442 {
443 is_trace_mode = 1;
444 printf_monitor (STEP_CMD);
445 /* wait for the echo. **
c5aa993b
JM
446 expect (STEP_CMD, 1);
447 */
c906108c
SS
448 }
449 else
450 {
451 printf_monitor (GO_CMD);
452 /* swallow the echo. **
c5aa993b
JM
453 expect (GO_CMD, 1);
454 */
c906108c
SS
455 }
456 bufaddr = 0;
c5aa993b 457 buflen = 0;
c906108c
SS
458}
459
460/*
461 * Wait until the remote machine stops, then return,
462 * storing status in status just as `wait' would.
463 */
464
39f77062
KB
465static ptid *
466rombug_wait (ptid_t ptid, struct target_waitstatus *status)
c906108c
SS
467{
468 int old_timeout = timeout;
469 struct section_offsets *offs;
470 CORE_ADDR addr, pc;
471 struct obj_section *obj_sec;
472
473 if (monitor_log)
474 fputs ("\nIn wait ()", log_file);
475
476 status->kind = TARGET_WAITKIND_EXITED;
477 status->value.integer = 0;
478
c5aa993b
JM
479 timeout = -1; /* Don't time out -- user program is running. */
480 expect ("eax:", 0); /* output any message before register display */
481 expect_prompt (1); /* Wait for prompt, outputting extraneous text */
c906108c
SS
482
483 status->kind = TARGET_WAITKIND_STOPPED;
484 status->value.sig = TARGET_SIGNAL_TRAP;
485 timeout = old_timeout;
c5aa993b 486 rombug_fetch_registers ();
c906108c
SS
487 bufaddr = 0;
488 buflen = 0;
c5aa993b
JM
489 pc = read_register (PC_REGNUM);
490 addr = read_register (DATABASE_REG);
c906108c
SS
491 obj_sec = find_pc_section (pc);
492 if (obj_sec != NULL)
493 {
494 if (obj_sec->objfile != symfile_objfile)
c5aa993b 495 new_symfile_objfile (obj_sec->objfile, 1, 0);
d4f3574e
SS
496 offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
497 memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
f0a58b0b
EZ
498 offs->offsets[SECT_OFF_DATA (symfile_objfile)] = addr;
499 offs->offsets[SECT_OFF_BSS (symfile_objfile)] = addr;
c906108c 500
c5aa993b 501 objfile_relocate (symfile_objfile, offs);
c906108c
SS
502 }
503
39f77062 504 return inferior_ptid;
c906108c
SS
505}
506
507/* Return the name of register number regno in the form input and output by
508 monitor. Currently, register_names just happens to contain exactly what
509 monitor wants. Lets take advantage of that just as long as possible! */
510
511static char *
fba45db2 512get_reg_name (int regno)
c906108c
SS
513{
514 static char buf[50];
515 char *p;
516 char *b;
517
518 b = buf;
519
520 if (regno < 0)
521 return ("");
522/*
c5aa993b
JM
523 for (p = REGISTER_NAME (regno); *p; p++)
524 *b++ = toupper(*p);
525 *b = '\000';
526 */
527 p = (char *) REGISTER_NAME (regno);
c906108c
SS
528 return p;
529/*
c5aa993b
JM
530 return buf;
531 */
c906108c
SS
532}
533
534/* read the remote registers into the block regs. */
535
536static void
fba45db2 537rombug_fetch_registers (void)
c906108c
SS
538{
539 int regno, j, i;
540 long val;
541 unsigned char b;
542
543 printf_monitor (GET_REG);
c5aa993b
JM
544 expect ("eax:", 1);
545 expect ("\n", 1);
546 get_hex_regs (1, 0);
547 get_hex_regs (1, 3);
548 get_hex_regs (1, 1);
549 get_hex_regs (1, 2);
550 get_hex_regs (1, 6);
551 get_hex_regs (1, 7);
552 get_hex_regs (1, 5);
553 get_hex_regs (1, 4);
c906108c
SS
554 for (regno = 8; regno <= 15; regno++)
555 {
c5aa993b 556 expect (REG_DELIM, 1);
c906108c
SS
557 if (regno >= 8 && regno <= 13)
558 {
559 val = 0;
560 for (j = 0; j < 2; j++)
c5aa993b
JM
561 {
562 get_hex_byte (&b);
d7449b42 563 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
c906108c
SS
564 val = (val << 8) + b;
565 else
c5aa993b
JM
566 val = val + (b << (j * 8));
567 }
c906108c 568
c5aa993b
JM
569 if (regno == 8)
570 i = 10;
571 if (regno >= 9 && regno <= 12)
572 i = regno + 3;
573 if (regno == 13)
574 i = 11;
c906108c
SS
575 supply_register (i, (char *) &val);
576 }
577 else if (regno == 14)
578 {
c5aa993b 579 get_hex_regs (1, PC_REGNUM);
c906108c
SS
580 }
581 else if (regno == 15)
582 {
c5aa993b 583 get_hex_regs (1, 9);
c906108c
SS
584 }
585 else
586 {
587 val = 0;
c5aa993b 588 supply_register (regno, (char *) &val);
c906108c
SS
589 }
590 }
591 is_trace_mode = 0;
592 expect_prompt (1);
593}
594
595/* Fetch register REGNO, or all registers if REGNO is -1.
596 Returns errno value. */
597static void
fba45db2 598rombug_fetch_register (int regno)
c906108c
SS
599{
600 int val, j;
601 unsigned char b;
602
c5aa993b
JM
603 if (monitor_log)
604 {
605 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
606 fflush (log_file);
607 }
c906108c
SS
608
609 if (regno < 0)
610 {
611 rombug_fetch_registers ();
612 }
613 else
614 {
615 char *name = get_reg_name (regno);
616 printf_monitor (GET_REG);
617 if (regno >= 10 && regno <= 15)
618 {
619 expect ("\n", 1);
620 expect ("\n", 1);
c5aa993b
JM
621 expect (name, 1);
622 expect (REG_DELIM, 1);
c906108c
SS
623 val = 0;
624 for (j = 0; j < 2; j++)
c5aa993b
JM
625 {
626 get_hex_byte (&b);
d7449b42 627 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
c906108c
SS
628 val = (val << 8) + b;
629 else
c5aa993b
JM
630 val = val + (b << (j * 8));
631 }
c906108c
SS
632 supply_register (regno, (char *) &val);
633 }
634 else if (regno == 8 || regno == 9)
635 {
636 expect ("\n", 1);
637 expect ("\n", 1);
638 expect ("\n", 1);
c5aa993b
JM
639 expect (name, 1);
640 expect (REG_DELIM, 1);
c906108c
SS
641 get_hex_regs (1, regno);
642 }
643 else
644 {
c5aa993b
JM
645 expect (name, 1);
646 expect (REG_DELIM, 1);
647 expect ("\n", 1);
648 get_hex_regs (1, 0);
649 get_hex_regs (1, 3);
650 get_hex_regs (1, 1);
651 get_hex_regs (1, 2);
652 get_hex_regs (1, 6);
653 get_hex_regs (1, 7);
654 get_hex_regs (1, 5);
655 get_hex_regs (1, 4);
c906108c
SS
656 }
657 expect_prompt (1);
658 }
659 return;
660}
661
662/* Store the remote registers from the contents of the block REGS. */
663
664static void
fba45db2 665rombug_store_registers (void)
c906108c
SS
666{
667 int regno;
668
669 for (regno = 0; regno <= PC_REGNUM; regno++)
c5aa993b 670 rombug_store_register (regno);
c906108c
SS
671
672 registers_changed ();
673}
674
675/* Store register REGNO, or all if REGNO == 0.
676 return errno value. */
677static void
fba45db2 678rombug_store_register (int regno)
c906108c 679{
c5aa993b 680 char *name;
c906108c
SS
681
682 if (monitor_log)
683 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
684
685 if (regno == -1)
686 rombug_store_registers ();
687 else
688 {
c5aa993b 689 if (sr_get_debug ())
c906108c
SS
690 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
691
c5aa993b
JM
692 name = get_reg_name (regno);
693 if (name == 0)
694 return;
c906108c
SS
695 printf_monitor (SET_REG, name, read_register (regno));
696
697 is_trace_mode = 0;
698 expect_prompt (1);
699 }
700}
701
702/* Get ready to modify the registers array. On machines which store
703 individual registers, this doesn't need to do anything. On machines
704 which store all the registers in one fell swoop, this makes sure
705 that registers contains all the registers from the program being
706 debugged. */
707
708static void
fba45db2 709rombug_prepare_to_store (void)
c906108c
SS
710{
711 /* Do nothing, since we can store individual regs */
712}
713
714static void
fba45db2 715rombug_files_info (void)
c906108c
SS
716{
717 printf ("\tAttached to %s at %d baud.\n",
c5aa993b 718 dev_name, sr_get_baud_rate ());
c906108c
SS
719}
720
721/* Copy LEN bytes of data from debugger memory at MYADDR
722 to inferior's memory at MEMADDR. Returns length moved. */
723static int
fba45db2 724rombug_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
c906108c
SS
725{
726 int i;
727 char buf[10];
728
729 if (monitor_log)
730 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
731
732 printf_monitor (MEM_SET_CMD, memaddr);
733 for (i = 0; i < len; i++)
734 {
735 expect (CMD_DELIM, 1);
736 printf_monitor ("%x \r", myaddr[i]);
c5aa993b 737 if (sr_get_debug ())
c906108c
SS
738 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
739 }
740 expect (CMD_DELIM, 1);
741 if (CMD_END)
742 printf_monitor (CMD_END);
743 is_trace_mode = 0;
744 expect_prompt (1);
745
746 bufaddr = 0;
747 buflen = 0;
748 return len;
749}
750
751/* Read LEN bytes from inferior memory at MEMADDR. Put the result
752 at debugger address MYADDR. Returns length moved. */
753static int
fba45db2 754rombug_read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
c906108c
SS
755{
756 int i, j;
757
758 /* Number of bytes read so far. */
759 int count;
760
761 /* Starting address of this pass. */
762 unsigned long startaddr;
763
764 /* Number of bytes to read in this pass. */
765 int len_this_pass;
766
767 if (monitor_log)
768 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
769
770 /* Note that this code works correctly if startaddr is just less
771 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
772 thing). That is, something like
773 rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
774 works--it never adds len To memaddr and gets 0. */
775 /* However, something like
776 rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
777 doesn't need to work. Detect it and give up if there's an attempt
778 to do that. */
c5aa993b
JM
779 if (((memaddr - 1) + len) < memaddr)
780 {
781 errno = EIO;
782 return 0;
783 }
784 if (bufaddr <= memaddr && (memaddr + len) <= (bufaddr + buflen))
c906108c 785 {
c5aa993b 786 memcpy (myaddr, &readbuf[memaddr - bufaddr], len);
c906108c
SS
787 return len;
788 }
c5aa993b 789
c906108c
SS
790 startaddr = memaddr;
791 count = 0;
792 while (count < len)
793 {
794 len_this_pass = 16;
795 if ((startaddr % 16) != 0)
796 len_this_pass -= startaddr % 16;
797 if (len_this_pass > (len - count))
798 len_this_pass = (len - count);
c5aa993b 799 if (sr_get_debug ())
c906108c
SS
800 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
801
802 printf_monitor (MEM_DIS_CMD, startaddr, 8);
803 expect ("- ", 1);
804 for (i = 0; i < 16; i++)
805 {
806 get_hex_byte (&readbuf[i]);
807 }
808 bufaddr = startaddr;
809 buflen = 16;
c5aa993b 810 memcpy (&myaddr[count], readbuf, len_this_pass);
c906108c
SS
811 count += len_this_pass;
812 startaddr += len_this_pass;
c5aa993b 813 expect (CMD_DELIM, 1);
c906108c 814 }
c5aa993b
JM
815 if (CMD_END)
816 printf_monitor (CMD_END);
c906108c
SS
817 is_trace_mode = 0;
818 expect_prompt (1);
819
820 return len;
821}
822
120abad8
KB
823/* Transfer LEN bytes between GDB address MYADDR and target address
824 MEMADDR. If WRITE is non-zero, transfer them to the target,
825 otherwise transfer them from the target. TARGET is unused.
826
827 Returns the number of bytes transferred. */
828
c906108c 829static int
120abad8 830rombug_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
0a65a603
AC
831 int write, struct mem_attrib *attrib,
832 struct target_ops *target)
c906108c
SS
833{
834 if (write)
835 return rombug_write_inferior_memory (memaddr, myaddr, len);
836 else
837 return rombug_read_inferior_memory (memaddr, myaddr, len);
838}
839
840static void
fba45db2 841rombug_kill (char *args, int from_tty)
c906108c 842{
c5aa993b 843 return; /* ignore attempts to kill target system */
c906108c
SS
844}
845
846/* Clean up when a program exits.
847 The program actually lives on in the remote processor's RAM, and may be
848 run again without a download. Don't leave it full of breakpoint
849 instructions. */
850
851static void
fba45db2 852rombug_mourn_inferior (void)
c906108c
SS
853{
854 remove_breakpoints ();
855 generic_mourn_inferior (); /* Do all the proper things now */
856}
857
858#define MAX_MONITOR_BREAKPOINTS 16
859
c5aa993b
JM
860static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] =
861{0};
c906108c
SS
862
863static int
fba45db2 864rombug_insert_breakpoint (CORE_ADDR addr, char *shadow)
c906108c
SS
865{
866 int i;
867 CORE_ADDR bp_addr = addr;
868 int bp_size = 0;
869
870 if (monitor_log)
871 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
872 BREAKPOINT_FROM_PC (&bp_addr, &bp_size);
873
874 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
875 if (breakaddr[i] == 0)
876 {
877 breakaddr[i] = addr;
c5aa993b 878 if (sr_get_debug ())
c906108c
SS
879 printf ("Breakpoint at %x\n", addr);
880 rombug_read_inferior_memory (bp_addr, shadow, bp_size);
c5aa993b 881 printf_monitor (SET_BREAK_CMD, addr);
c906108c 882 is_trace_mode = 0;
c5aa993b 883 expect_prompt (1);
c906108c
SS
884 return 0;
885 }
886
f8d17dc5 887 fprintf_unfiltered (gdb_stderr, "Too many breakpoints (> 16) for monitor\n");
c906108c
SS
888 return 1;
889}
890
891/*
892 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
893 */
894static int
fba45db2 895rombug_remove_breakpoint (CORE_ADDR addr, char *shadow)
c906108c
SS
896{
897 int i;
898
899 if (monitor_log)
900 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
901
902 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
903 if (breakaddr[i] == addr)
904 {
905 breakaddr[i] = 0;
c5aa993b 906 printf_monitor (CLR_BREAK_CMD, addr);
c906108c 907 is_trace_mode = 0;
c5aa993b 908 expect_prompt (1);
c906108c
SS
909 return 0;
910 }
911
f8d17dc5
PM
912 fprintf_unfiltered (gdb_stderr,
913 "Can't find breakpoint associated with 0x%x\n", addr);
c906108c
SS
914 return 1;
915}
916
917/* Load a file. This is usually an srecord, which is ascii. No
918 protocol, just sent line by line. */
919
920#define DOWNLOAD_LINE_SIZE 100
921static void
fba45db2 922rombug_load (char *arg)
c906108c
SS
923{
924/* this part comment out for os9* */
925#if 0
926 FILE *download;
927 char buf[DOWNLOAD_LINE_SIZE];
928 int i, bytes_read;
929
c5aa993b 930 if (sr_get_debug ())
c906108c
SS
931 printf ("Loading %s to monitor\n", arg);
932
933 download = fopen (arg, "r");
934 if (download == NULL)
935 {
c5aa993b
JM
936 error (sprintf (buf, "%s Does not exist", arg));
937 return;
938 }
c906108c
SS
939
940 printf_monitor (LOAD_CMD);
941/* expect ("Waiting for S-records from host... ", 1); */
942
943 while (!feof (download))
944 {
945 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
946 if (hashmark)
947 {
948 putchar ('.');
949 fflush (stdout);
950 }
951
2cd58942 952 if (serial_write (monitor_desc, buf, bytes_read))
c5aa993b 953 {
f8d17dc5
PM
954 fprintf_unfiltered (gdb_stderr,
955 "serial_write failed: (while downloading) %s\n",
956 safe_strerror (errno));
c5aa993b
JM
957 break;
958 }
c906108c 959 i = 0;
c5aa993b
JM
960 while (i++ <= 200000)
961 {
962 }; /* Ugly HACK, probably needs flow control */
c906108c
SS
963 if (bytes_read < DOWNLOAD_LINE_SIZE)
964 {
965 if (!feof (download))
966 error ("Only read %d bytes\n", bytes_read);
967 break;
968 }
969 }
970
971 if (hashmark)
972 {
973 putchar ('\n');
974 }
975 if (!feof (download))
976 error ("Never got EOF while downloading");
977 fclose (download);
c5aa993b 978#endif /* 0 */
c906108c
SS
979}
980
981/* Put a command string, in args, out to MONITOR.
982 Output from MONITOR is placed on the users terminal until the prompt
983 is seen. */
984
985static void
fba45db2 986rombug_command (char *args, int fromtty)
c906108c
SS
987{
988 if (monitor_desc == NULL)
c5aa993b
JM
989 error ("monitor target not open.");
990
c906108c
SS
991 if (monitor_log)
992 fprintf (log_file, "\nIn command (args=%s)\n", args);
993
994 if (!args)
c5aa993b
JM
995 error ("Missing command.");
996
997 printf_monitor ("%s\r", args);
998 expect_prompt (0);
c906108c
SS
999}
1000
1001#if 0
1002/* Connect the user directly to MONITOR. This command acts just like the
1003 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
1004
1005static struct ttystate ttystate;
1006
1007static void
fba45db2 1008cleanup_tty (void)
c5aa993b
JM
1009{
1010 printf ("\r\n[Exiting connect mode]\r\n");
2cd58942 1011 /*serial_restore(0, &ttystate); */
c906108c
SS
1012}
1013
1014static void
fba45db2 1015connect_command (char *args, int fromtty)
c906108c
SS
1016{
1017 fd_set readfds;
1018 int numfds;
1019 int c;
1020 char cur_esc = 0;
1021
c5aa993b 1022 dont_repeat ();
c906108c
SS
1023
1024 if (monitor_desc == NULL)
c5aa993b
JM
1025 error ("monitor target not open.");
1026
c906108c 1027 if (args)
c5aa993b
JM
1028 fprintf ("This command takes no args. They have been ignored.\n");
1029
1030 printf ("[Entering connect mode. Use ~. or ~^D to escape]\n");
c906108c 1031
c5aa993b 1032 serial_raw (0, &ttystate);
c906108c 1033
c5aa993b 1034 make_cleanup (cleanup_tty, 0);
c906108c 1035
c5aa993b 1036 FD_ZERO (&readfds);
c906108c
SS
1037
1038 while (1)
1039 {
1040 do
1041 {
c5aa993b 1042 FD_SET (0, &readfds);
2cd58942 1043 FD_SET (deprecated_serial_fd (monitor_desc), &readfds);
c5aa993b 1044 numfds = select (sizeof (readfds) * 8, &readfds, 0, 0, 0);
c906108c
SS
1045 }
1046 while (numfds == 0);
1047
1048 if (numfds < 0)
c5aa993b 1049 perror_with_name ("select");
c906108c 1050
c5aa993b 1051 if (FD_ISSET (0, &readfds))
c906108c 1052 { /* tty input, send to monitor */
c5aa993b 1053 c = getchar ();
c906108c 1054 if (c < 0)
c5aa993b 1055 perror_with_name ("connect");
c906108c 1056
c5aa993b 1057 printf_monitor ("%c", c);
c906108c
SS
1058 switch (cur_esc)
1059 {
1060 case 0:
1061 if (c == '\r')
1062 cur_esc = c;
1063 break;
1064 case '\r':
1065 if (c == '~')
1066 cur_esc = c;
1067 else
1068 cur_esc = 0;
1069 break;
1070 case '~':
1071 if (c == '.' || c == '\004')
1072 return;
1073 else
1074 cur_esc = 0;
1075 }
1076 }
1077
2cd58942 1078 if (FD_ISSET (deprecated_serial_fd (monitor_desc), &readfds))
c906108c
SS
1079 {
1080 while (1)
1081 {
c5aa993b 1082 c = readchar (0);
c906108c
SS
1083 if (c < 0)
1084 break;
c5aa993b 1085 putchar (c);
c906108c 1086 }
c5aa993b 1087 fflush (stdout);
c906108c
SS
1088 }
1089 }
1090}
1091#endif
1092
1093/*
1094 * Define the monitor command strings. Since these are passed directly
1095 * through to a printf style function, we need can include formatting
1096 * strings. We also need a CR or LF on the end.
1097 */
1098#warning FIXME: monitor interface pattern strings, stale struct decl
c5aa993b
JM
1099struct monitor_ops rombug_cmds =
1100{
1101 "g \r", /* execute or usually GO command */
1102 "g \r", /* continue command */
1103 "t \r", /* single step */
1104 "b %x\r", /* set a breakpoint */
1105 "k %x\r", /* clear a breakpoint */
1106 "c %x\r", /* set memory to a value */
1107 "d %x %d\r", /* display memory */
1108 "$%08X", /* prompt memory commands use */
1109 ".%s %x\r", /* set a register */
1110 ":", /* delimiter between registers */
1111 ". \r", /* read a register */
1112 "mf \r", /* download command */
1113 "RomBug: ", /* monitor command prompt */
1114 ": ", /* end-of-command delimitor */
1115 ".\r" /* optional command terminator */
c906108c
SS
1116};
1117
c5aa993b 1118struct target_ops rombug_ops;
c906108c 1119
c5aa993b
JM
1120static void
1121init_rombug_ops (void)
c906108c 1122{
c5aa993b
JM
1123 rombug_ops.to_shortname = "rombug";
1124 rombug_ops.to_longname = "Microware's ROMBUG debug monitor";
1125 rombug_ops.to_doc = "Use a remote computer running the ROMBUG debug monitor.\n\
c906108c 1126Specify the serial device it is connected to (e.g. /dev/ttya).",
c5aa993b
JM
1127 rombug_ops.to_open = rombug_open;
1128 rombug_ops.to_close = rombug_close;
1129 rombug_ops.to_attach = 0;
c906108c
SS
1130 rombug_ops.to_post_attach = NULL;
1131 rombug_ops.to_require_attach = NULL;
c5aa993b 1132 rombug_ops.to_detach = rombug_detach;
c906108c 1133 rombug_ops.to_require_detach = NULL;
c5aa993b
JM
1134 rombug_ops.to_resume = rombug_resume;
1135 rombug_ops.to_wait = rombug_wait;
c906108c 1136 rombug_ops.to_post_wait = NULL;
c5aa993b
JM
1137 rombug_ops.to_fetch_registers = rombug_fetch_register;
1138 rombug_ops.to_store_registers = rombug_store_register;
1139 rombug_ops.to_prepare_to_store = rombug_prepare_to_store;
1140 rombug_ops.to_xfer_memory = rombug_xfer_inferior_memory;
1141 rombug_ops.to_files_info = rombug_files_info;
1142 rombug_ops.to_insert_breakpoint = rombug_insert_breakpoint;
1143 rombug_ops.to_remove_breakpoint = rombug_remove_breakpoint; /* Breakpoints */
1144 rombug_ops.to_terminal_init = 0;
1145 rombug_ops.to_terminal_inferior = 0;
1146 rombug_ops.to_terminal_ours_for_output = 0;
1147 rombug_ops.to_terminal_ours = 0;
1148 rombug_ops.to_terminal_info = 0; /* Terminal handling */
1149 rombug_ops.to_kill = rombug_kill;
1150 rombug_ops.to_load = rombug_load; /* load */
1151 rombug_ops.to_lookup_symbol = rombug_link; /* lookup_symbol */
1152 rombug_ops.to_create_inferior = rombug_create_inferior;
c906108c
SS
1153 rombug_ops.to_post_startup_inferior = NULL;
1154 rombug_ops.to_acknowledge_created_inferior = NULL;
1155 rombug_ops.to_clone_and_follow_inferior = NULL;
1156 rombug_ops.to_post_follow_inferior_by_clone = NULL;
1157 rombug_ops.to_insert_fork_catchpoint = NULL;
1158 rombug_ops.to_remove_fork_catchpoint = NULL;
1159 rombug_ops.to_insert_vfork_catchpoint = NULL;
1160 rombug_ops.to_remove_vfork_catchpoint = NULL;
1161 rombug_ops.to_has_forked = NULL;
1162 rombug_ops.to_has_vforked = NULL;
1163 rombug_ops.to_can_follow_vfork_prior_to_exec = NULL;
1164 rombug_ops.to_post_follow_vfork = NULL;
1165 rombug_ops.to_insert_exec_catchpoint = NULL;
1166 rombug_ops.to_remove_exec_catchpoint = NULL;
1167 rombug_ops.to_has_execd = NULL;
1168 rombug_ops.to_reported_exec_events_per_exec_call = NULL;
1169 rombug_ops.to_has_exited = NULL;
c5aa993b
JM
1170 rombug_ops.to_mourn_inferior = rombug_mourn_inferior;
1171 rombug_ops.to_can_run = 0; /* can_run */
1172 rombug_ops.to_notice_signals = 0; /* notice_signals */
1173 rombug_ops.to_thread_alive = 0;
1174 rombug_ops.to_stop = 0; /* to_stop */
c906108c 1175 rombug_ops.to_pid_to_exec_file = NULL;
c5aa993b
JM
1176 rombug_ops.to_stratum = process_stratum;
1177 rombug_ops.DONT_USE = 0; /* next */
1178 rombug_ops.to_has_all_memory = 1;
1179 rombug_ops.to_has_memory = 1;
1180 rombug_ops.to_has_stack = 1;
1181 rombug_ops.to_has_registers = 1;
1182 rombug_ops.to_has_execution = 1; /* has execution */
1183 rombug_ops.to_sections = 0;
1184 rombug_ops.to_sections_end = 0; /* Section pointers */
1185 rombug_ops.to_magic = OPS_MAGIC; /* Always the last thing */
1186}
c906108c
SS
1187
1188void
fba45db2 1189_initialize_remote_os9k (void)
c906108c 1190{
c5aa993b 1191 init_rombug_ops ();
c906108c
SS
1192 add_target (&rombug_ops);
1193
1194 add_show_from_set (
c5aa993b
JM
1195 add_set_cmd ("hash", no_class, var_boolean, (char *) &hashmark,
1196 "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
1197 &setlist),
1198 &showlist);
c906108c
SS
1199
1200 add_show_from_set (
c5aa993b
JM
1201 add_set_cmd ("timeout", no_class, var_zinteger,
1202 (char *) &timeout,
1203 "Set timeout in seconds for remote MIPS serial I/O.",
1204 &setlist),
1205 &showlist);
c906108c
SS
1206
1207 add_show_from_set (
c5aa993b
JM
1208 add_set_cmd ("remotelog", no_class, var_zinteger,
1209 (char *) &monitor_log,
1210 "Set monitor activity log on(=1) or off(=0).",
1211 &setlist),
1212 &showlist);
c906108c
SS
1213
1214 add_show_from_set (
c5aa993b
JM
1215 add_set_cmd ("remotexon", no_class, var_zinteger,
1216 (char *) &tty_xon,
1217 "Set remote tty line XON control",
1218 &setlist),
1219 &showlist);
c906108c
SS
1220
1221 add_show_from_set (
c5aa993b
JM
1222 add_set_cmd ("remotexoff", no_class, var_zinteger,
1223 (char *) &tty_xoff,
1224 "Set remote tty line XOFF control",
1225 &setlist),
1226 &showlist);
c906108c
SS
1227
1228 add_com ("rombug <command>", class_obscure, rombug_command,
c5aa993b 1229 "Send a command to the debug monitor.");
c906108c
SS
1230#if 0
1231 add_com ("connect", class_obscure, connect_command,
c5aa993b 1232 "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");
c906108c
SS
1233#endif
1234}
This page took 0.428342 seconds and 4 git commands to generate.