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