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