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