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