]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/remote-os9k.c
Add GDBPROTO macro for checking the type of protocol.
[thirdparty/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);
1340861c 362 push_target (&rombug_ops);
034022bf
KH
363 attach_flag = 1;
364
1340861c
KH
365 if (from_tty)
366 printf("Remote %s connected to %s\n", target_shortname,
367 dev_name);
368
034022bf
KH
369 printf_monitor ("ov e \r");
370 expect_prompt(1);
371
1340861c 372 rombug_fetch_registers();
d5336fc5
KH
373 bufaddr = 0;
374 buflen = 0;
1340861c
KH
375}
376
377/*
378 * Close out all files and local state before this target loses control.
379 */
380
381static void
382rombug_close (quitting)
383 int quitting;
384{
385 if (rombug_is_open) {
386 SERIAL_CLOSE(monitor_desc);
387 monitor_desc = NULL;
388 rombug_is_open = 0;
389 }
390
1340861c
KH
391 if (log_file) {
392 if (ferror(log_file))
393 fprintf(stderr, "Error writing log file.\n");
394 if (fclose(log_file) != 0)
395 fprintf(stderr, "Error closing log file.\n");
396 log_file = 0;
397 }
1340861c
KH
398}
399
400int
401rombug_link(mod_name, text_reloc)
402 char *mod_name;
403 CORE_ADDR *text_reloc;
404{
405 int i, j;
406 unsigned long val;
407 unsigned char b;
408
409 printf_monitor("l %s \r", mod_name);
410 expect_prompt(1);
411 printf_monitor(".r \r");
412 expect(REG_DELIM, 1);
413 for (i=0; i <= 7; i++)
414 {
415 val = 0;
416 for (j = 0; j < 4; j++)
417 {
418 get_hex_byte(&b);
419 val = (val << 8) + b;
420 }
421 }
422 expect_prompt(1);
423 *text_reloc = val;
424 return 1;
425}
426
427/* Terminate the open connection to the remote debugger.
428 Use this when you want to detach and do something else
429 with your gdb. */
430static void
431rombug_detach (from_tty)
432 int from_tty;
433{
434 if (attach_flag) {
435 printf_monitor (GO_CMD);
436 attach_flag = 0;
437 }
438 pop_target(); /* calls rombug_close to do the real work */
439 if (from_tty)
440 printf ("Ending remote %s debugging\n", target_shortname);
441}
442
443/*
444 * Tell the remote machine to resume.
445 */
446static void
447rombug_resume (pid, step, sig)
448 int pid, step;
449 enum target_signal sig;
450{
d9389f37
KH
451 if (monitor_log)
452 fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
1340861c
KH
453
454 if (step)
455 {
456 is_trace_mode = 1;
457 printf_monitor (STEP_CMD);
d5336fc5 458 /* wait for the echo. **
1340861c 459 expect (STEP_CMD, 1);
d5336fc5 460 */
1340861c
KH
461 }
462 else
463 {
464 printf_monitor (GO_CMD);
d5336fc5 465 /* swallow the echo. **
1340861c 466 expect (GO_CMD, 1);
d5336fc5 467 */
1340861c 468 }
d5336fc5
KH
469 bufaddr = 0;
470 buflen= 0;
1340861c
KH
471}
472
473/*
474 * Wait until the remote machine stops, then return,
475 * storing status in status just as `wait' would.
476 */
477
478static int
479rombug_wait (pid, status)
480 int pid;
481 struct target_waitstatus *status;
482{
483 int old_timeout = timeout;
484 struct section_offsets *offs;
485 CORE_ADDR addr, pc;
25200748 486 struct obj_section *obj_sec;
1340861c 487
d9389f37
KH
488 if (monitor_log)
489 fputs ("\nIn wait ()", log_file);
1340861c
KH
490
491 status->kind = TARGET_WAITKIND_EXITED;
492 status->value.integer = 0;
493
034022bf
KH
494 timeout = -1; /* Don't time out -- user program is running. */
495 expect ("eax:", 0); /* output any message before register display */
1340861c
KH
496 expect_prompt(1); /* Wait for prompt, outputting extraneous text */
497
498 status->kind = TARGET_WAITKIND_STOPPED;
499 status->value.sig = TARGET_SIGNAL_TRAP;
500 timeout = old_timeout;
501 rombug_fetch_registers();
d5336fc5
KH
502 bufaddr = 0;
503 buflen = 0;
1340861c
KH
504 pc = read_register(PC_REGNUM);
505 addr = read_register(DATABASE_REG);
25200748
JK
506 obj_sec = find_pc_section (pc);
507 if (obj_sec != NULL)
d9389f37
KH
508 {
509 if (obj_sec->objfile != symfile_objfile)
510 new_symfile_objfile(obj_sec->objfile, 1, 0);
511 offs = ((struct section_offsets *)
1340861c
KH
512 alloca (sizeof (struct section_offsets)
513 + (symfile_objfile->num_sections * sizeof (offs->offsets))));
d9389f37 514 memcpy (offs, symfile_objfile->section_offsets,
1340861c
KH
515 (sizeof (struct section_offsets) +
516 (symfile_objfile->num_sections * sizeof (offs->offsets))));
d9389f37
KH
517 ANOFFSET (offs, SECT_OFF_DATA) = addr;
518 ANOFFSET (offs, SECT_OFF_BSS) = addr;
1340861c 519
d9389f37
KH
520 objfile_relocate(symfile_objfile, offs);
521 }
d5336fc5 522
1340861c
KH
523 return 0;
524}
525
526/* Return the name of register number regno in the form input and output by
527 monitor. Currently, register_names just happens to contain exactly what
528 monitor wants. Lets take advantage of that just as long as possible! */
529
530static char *
531get_reg_name (regno)
532 int regno;
533{
534 static char buf[50];
535 char *p;
536 char *b;
537
538 b = buf;
539
540 if (regno < 0)
541 return ("");
542/*
543 for (p = reg_names[regno]; *p; p++)
544 *b++ = toupper(*p);
545 *b = '\000';
546*/
547 p = (char *)reg_names[regno];
548 return p;
549/*
550 return buf;
551*/
552}
553
554/* read the remote registers into the block regs. */
555
556static void
557rombug_fetch_registers ()
558{
559 int regno, j, i;
560 long val;
561 unsigned char b;
562
563 printf_monitor (GET_REG);
564 expect("eax:", 1);
565 expect("\n", 1);
566 get_hex_regs(1, 0);
567 get_hex_regs(1, 3);
568 get_hex_regs(1, 1);
569 get_hex_regs(1, 2);
570 get_hex_regs(1, 6);
571 get_hex_regs(1, 7);
572 get_hex_regs(1, 5);
573 get_hex_regs(1, 4);
574 for (regno = 8; regno <= 15; regno++)
575 {
576 expect(REG_DELIM, 1);
577 if (regno >= 8 && regno <= 13)
578 {
579 val = 0;
580 for (j = 0; j < 2; j++)
581 {
b8176214
ILT
582 get_hex_byte (&b);
583 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
584 val = (val << 8) + b;
585 else
586 val = val + (b << (j*8));
1340861c
KH
587 }
588
589 if (regno == 8) i = 10;
590 if (regno >= 9 && regno <= 12) i = regno + 3;
591 if (regno == 13) i = 11;
592 supply_register (i, (char *) &val);
593 }
594 else if (regno == 14)
595 {
596 get_hex_regs(1, PC_REGNUM);
597 }
598 else if (regno == 15)
599 {
600 get_hex_regs(1, 9);
601 }
602 else
603 {
604 val = 0;
605 supply_register(regno, (char *) &val);
606 }
607 }
d5336fc5 608 is_trace_mode = 0;
1340861c
KH
609 expect_prompt (1);
610}
611
612/* Fetch register REGNO, or all registers if REGNO is -1.
613 Returns errno value. */
614static void
615rombug_fetch_register (regno)
616 int regno;
617{
618 int val, j;
619 unsigned char b;
620
d9389f37
KH
621 if (monitor_log) {
622 fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
623 fflush (log_file);
624 }
1340861c
KH
625
626 if (regno < 0)
627 {
628 rombug_fetch_registers ();
629 }
630 else
631 {
632 char *name = get_reg_name (regno);
633 printf_monitor (GET_REG);
634 if (regno >= 10 && regno <= 15)
635 {
636 expect ("\n", 1);
637 expect ("\n", 1);
638 expect (name, 1);
639 expect (REG_DELIM, 1);
640 val = 0;
641 for (j = 0; j < 2; j++)
642 {
b8176214
ILT
643 get_hex_byte (&b);
644 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
645 val = (val << 8) + b;
646 else
647 val = val + (b << (j*8));
1340861c
KH
648 }
649 supply_register (regno, (char *) &val);
650 }
651 else if (regno == 8 || regno == 9)
652 {
653 expect ("\n", 1);
654 expect ("\n", 1);
655 expect ("\n", 1);
656 expect (name, 1);
657 expect (REG_DELIM, 1);
658 get_hex_regs (1, regno);
659 }
660 else
661 {
662 expect (name, 1);
663 expect (REG_DELIM, 1);
664 expect("\n", 1);
665 get_hex_regs(1, 0);
666 get_hex_regs(1, 3);
667 get_hex_regs(1, 1);
668 get_hex_regs(1, 2);
669 get_hex_regs(1, 6);
670 get_hex_regs(1, 7);
671 get_hex_regs(1, 5);
672 get_hex_regs(1, 4);
673 }
674 expect_prompt (1);
675 }
676 return;
677}
678
679/* Store the remote registers from the contents of the block REGS. */
680
681static void
682rombug_store_registers ()
683{
684 int regno;
685
686 for (regno = 0; regno <= PC_REGNUM; regno++)
687 rombug_store_register(regno);
688
689 registers_changed ();
690}
691
692/* Store register REGNO, or all if REGNO == 0.
693 return errno value. */
694static void
695rombug_store_register (regno)
696 int regno;
697{
698char *name;
699
d9389f37
KH
700 if (monitor_log)
701 fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
702
1340861c
KH
703 if (regno == -1)
704 rombug_store_registers ();
705 else
706 {
707 if (sr_get_debug())
708 printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
709
710 name = get_reg_name(regno);
711 if (name == 0) return;
712 printf_monitor (SET_REG, name, read_register (regno));
713
d5336fc5 714 is_trace_mode = 0;
1340861c
KH
715 expect_prompt (1);
716 }
717}
718
719/* Get ready to modify the registers array. On machines which store
720 individual registers, this doesn't need to do anything. On machines
721 which store all the registers in one fell swoop, this makes sure
722 that registers contains all the registers from the program being
723 debugged. */
724
725static void
726rombug_prepare_to_store ()
727{
728 /* Do nothing, since we can store individual regs */
729}
730
731static void
732rombug_files_info ()
733{
734 printf ("\tAttached to %s at %d baud.\n",
d9389f37 735 dev_name, sr_get_baud_rate());
1340861c
KH
736}
737
738/* Copy LEN bytes of data from debugger memory at MYADDR
739 to inferior's memory at MEMADDR. Returns length moved. */
740static int
741rombug_write_inferior_memory (memaddr, myaddr, len)
742 CORE_ADDR memaddr;
743 unsigned char *myaddr;
744 int len;
745{
746 int i;
747 char buf[10];
748
d9389f37
KH
749 if (monitor_log)
750 fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
751
752 printf_monitor (MEM_SET_CMD, memaddr);
1340861c
KH
753 for (i = 0; i < len; i++)
754 {
755 expect (CMD_DELIM, 1);
d9389f37 756 printf_monitor ("%x \r", myaddr[i]);
1340861c
KH
757 if (sr_get_debug())
758 printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
759 }
d9389f37 760 expect (CMD_DELIM, 1);
1340861c
KH
761 if (CMD_END)
762 printf_monitor (CMD_END);
d5336fc5 763 is_trace_mode = 0;
1340861c
KH
764 expect_prompt (1);
765
766 return len;
767}
768
769/* Read LEN bytes from inferior memory at MEMADDR. Put the result
770 at debugger address MYADDR. Returns length moved. */
771static int
772rombug_read_inferior_memory(memaddr, myaddr, len)
773 CORE_ADDR memaddr;
774 char *myaddr;
775 int len;
776{
777 int i, j;
1340861c
KH
778
779 /* Number of bytes read so far. */
780 int count;
781
782 /* Starting address of this pass. */
783 unsigned long startaddr;
784
785 /* Number of bytes to read in this pass. */
786 int len_this_pass;
787
d9389f37
KH
788 if (monitor_log)
789 fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
1340861c
KH
790
791 /* Note that this code works correctly if startaddr is just less
792 than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
793 thing). That is, something like
794 rombug_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
795 works--it never adds len To memaddr and gets 0. */
796 /* However, something like
797 rombug_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
798 doesn't need to work. Detect it and give up if there's an attempt
799 to do that. */
800 if (((memaddr - 1) + len) < memaddr) {
801 errno = EIO;
802 return 0;
803 }
d5336fc5
KH
804 if (bufaddr <= memaddr && (memaddr+len) <= (bufaddr+buflen))
805 {
806 memcpy(myaddr, &readbuf[memaddr-bufaddr], len);
807 return len;
808 }
1340861c
KH
809
810 startaddr = memaddr;
811 count = 0;
812 while (count < len)
813 {
814 len_this_pass = 16;
815 if ((startaddr % 16) != 0)
816 len_this_pass -= startaddr % 16;
817 if (len_this_pass > (len - count))
818 len_this_pass = (len - count);
819 if (sr_get_debug())
820 printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
821
d5336fc5 822 printf_monitor (MEM_DIS_CMD, startaddr, 8);
1340861c 823 expect ("- ", 1);
d5336fc5 824 for (i = 0; i < 16; i++)
1340861c 825 {
d5336fc5 826 get_hex_byte (&readbuf[i]);
1340861c 827 }
d5336fc5
KH
828 bufaddr = startaddr;
829 buflen = 16;
830 memcpy(&myaddr[count], readbuf, len_this_pass);
831 count += len_this_pass;
832 startaddr += len_this_pass;
1340861c
KH
833 expect(CMD_DELIM, 1);
834 }
835 if (CMD_END)
836 printf_monitor (CMD_END);
d5336fc5 837 is_trace_mode = 0;
1340861c
KH
838 expect_prompt (1);
839
840 return len;
841}
842
843/* FIXME-someday! merge these two. */
844static int
845rombug_xfer_inferior_memory (memaddr, myaddr, len, write, target)
846 CORE_ADDR memaddr;
847 char *myaddr;
848 int len;
849 int write;
850 struct target_ops *target; /* ignored */
851{
852 if (write)
853 return rombug_write_inferior_memory (memaddr, myaddr, len);
854 else
855 return rombug_read_inferior_memory (memaddr, myaddr, len);
856}
857
858static void
859rombug_kill (args, from_tty)
860 char *args;
861 int from_tty;
862{
863 return; /* ignore attempts to kill target system */
864}
865
866/* Clean up when a program exits.
867 The program actually lives on in the remote processor's RAM, and may be
868 run again without a download. Don't leave it full of breakpoint
869 instructions. */
870
871static void
872rombug_mourn_inferior ()
873{
874 remove_breakpoints ();
875 generic_mourn_inferior (); /* Do all the proper things now */
876}
877
878#define MAX_MONITOR_BREAKPOINTS 16
879
880extern int memory_breakpoint_size;
881static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
882
883static int
884rombug_insert_breakpoint (addr, shadow)
885 CORE_ADDR addr;
886 char *shadow;
887{
888 int i;
889
d9389f37
KH
890 if (monitor_log)
891 fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
892
1340861c
KH
893 for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
894 if (breakaddr[i] == 0)
895 {
896 breakaddr[i] = addr;
897 if (sr_get_debug())
898 printf ("Breakpoint at %x\n", addr);
899 rombug_read_inferior_memory(addr, shadow, memory_breakpoint_size);
900 printf_monitor(SET_BREAK_CMD, addr);
d5336fc5 901 is_trace_mode = 0;
1340861c
KH
902 expect_prompt(1);
903 return 0;
904 }
905
906 fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
907 return 1;
908}
909
910/*
911 * _remove_breakpoint -- Tell the monitor to remove a breakpoint
912 */
913static int
914rombug_remove_breakpoint (addr, shadow)
915 CORE_ADDR addr;
916 char *shadow;
917{
918 int i;
919
d9389f37
KH
920 if (monitor_log)
921 fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
922
1340861c
KH
923 for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
924 if (breakaddr[i] == addr)
925 {
926 breakaddr[i] = 0;
d9389f37 927 printf_monitor(CLR_BREAK_CMD, addr);
d5336fc5 928 is_trace_mode = 0;
1340861c
KH
929 expect_prompt(1);
930 return 0;
931 }
932
933 fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
934 return 1;
935}
936
937/* Load a file. This is usually an srecord, which is ascii. No
938 protocol, just sent line by line. */
939
940#define DOWNLOAD_LINE_SIZE 100
941static void
942rombug_load (arg)
943 char *arg;
944{
945/* this part comment out for os9* */
946#if 0
947 FILE *download;
948 char buf[DOWNLOAD_LINE_SIZE];
949 int i, bytes_read;
950
951 if (sr_get_debug())
952 printf ("Loading %s to monitor\n", arg);
953
954 download = fopen (arg, "r");
955 if (download == NULL)
956 {
957 error (sprintf (buf, "%s Does not exist", arg));
958 return;
959 }
960
961 printf_monitor (LOAD_CMD);
962/* expect ("Waiting for S-records from host... ", 1); */
963
964 while (!feof (download))
965 {
966 bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
967 if (hashmark)
968 {
969 putchar ('.');
970 fflush (stdout);
971 }
972
973 if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
974 fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
975 break;
976 }
977 i = 0;
978 while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
979 if (bytes_read < DOWNLOAD_LINE_SIZE)
980 {
981 if (!feof (download))
982 error ("Only read %d bytes\n", bytes_read);
983 break;
984 }
985 }
986
987 if (hashmark)
988 {
989 putchar ('\n');
990 }
991 if (!feof (download))
992 error ("Never got EOF while downloading");
993 fclose (download);
994#endif 0
995}
996
997/* Put a command string, in args, out to MONITOR.
998 Output from MONITOR is placed on the users terminal until the prompt
999 is seen. */
1000
1001static void
1002rombug_command (args, fromtty)
1003 char *args;
1004 int fromtty;
1005{
1340861c
KH
1006 if (monitor_desc == NULL)
1007 error("monitor target not open.");
1008
d9389f37
KH
1009 if (monitor_log)
1010 fprintf (log_file, "\nIn command (args=%s)\n", args);
1011
1340861c
KH
1012 if (!args)
1013 error("Missing command.");
1014
1015 printf_monitor("%s\r", args);
539dccd3 1016 expect_prompt(0);
1340861c
KH
1017}
1018
1019#if 0
1020/* Connect the user directly to MONITOR. This command acts just like the
1021 'cu' or 'tip' command. Use <CR>~. or <CR>~^D to break out. */
1022
1023static struct ttystate ttystate;
1024
1025static void
1026cleanup_tty()
1027{ printf("\r\n[Exiting connect mode]\r\n");
1028 /*SERIAL_RESTORE(0, &ttystate);*/
1029}
1030
1031static void
1032connect_command (args, fromtty)
1033 char *args;
1034 int fromtty;
1035{
1036 fd_set readfds;
1037 int numfds;
1038 int c;
1039 char cur_esc = 0;
1040
1041 dont_repeat();
1042
1043 if (monitor_desc == NULL)
1044 error("monitor target not open.");
1045
1046 if (args)
1047 fprintf("This command takes no args. They have been ignored.\n");
1048
1049 printf("[Entering connect mode. Use ~. or ~^D to escape]\n");
1050
1051 serial_raw(0, &ttystate);
1052
1053 make_cleanup(cleanup_tty, 0);
1054
1055 FD_ZERO(&readfds);
1056
1057 while (1)
1058 {
1059 do
1060 {
1061 FD_SET(0, &readfds);
1062 FD_SET(monitor_desc, &readfds);
1063 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1064 }
1065 while (numfds == 0);
1066
1067 if (numfds < 0)
1068 perror_with_name("select");
1069
1070 if (FD_ISSET(0, &readfds))
1071 { /* tty input, send to monitor */
1072 c = getchar();
1073 if (c < 0)
1074 perror_with_name("connect");
1075
1076 printf_monitor("%c", c);
1077 switch (cur_esc)
1078 {
1079 case 0:
1080 if (c == '\r')
1081 cur_esc = c;
1082 break;
1083 case '\r':
1084 if (c == '~')
1085 cur_esc = c;
1086 else
1087 cur_esc = 0;
1088 break;
1089 case '~':
1090 if (c == '.' || c == '\004')
1091 return;
1092 else
1093 cur_esc = 0;
1094 }
1095 }
1096
1097 if (FD_ISSET(monitor_desc, &readfds))
1098 {
1099 while (1)
1100 {
1101 c = readchar(0);
1102 if (c < 0)
1103 break;
1104 putchar(c);
1105 }
1106 fflush(stdout);
1107 }
1108 }
1109}
1110#endif
1111
1112/*
1113 * Define the monitor command strings. Since these are passed directly
1114 * through to a printf style function, we need can include formatting
1115 * strings. We also need a CR or LF on the end.
1116 */
1117struct monitor_ops rombug_cmds = {
1118 "g \r", /* execute or usually GO command */
1119 "g \r", /* continue command */
d9389f37 1120 "t \r", /* single step */
1340861c
KH
1121 "b %x\r", /* set a breakpoint */
1122 "k %x\r", /* clear a breakpoint */
1123 "c %x\r", /* set memory to a value */
1124 "d %x %d\r", /* display memory */
1125 "$%08X", /* prompt memory commands use */
1126 ".%s %x\r", /* set a register */
1127 ":", /* delimiter between registers */
1128 ". \r", /* read a register */
1129 "mf \r", /* download command */
1130 "RomBug: ", /* monitor command prompt */
1131 ": ", /* end-of-command delimitor */
1132 ".\r" /* optional command terminator */
1133};
1134
1135struct target_ops rombug_ops = {
1136 "rombug",
1137 "Microware's ROMBUG debug monitor",
1138 "Use a remote computer running the ROMBUG debug monitor.\n\
1139Specify the serial device it is connected to (e.g. /dev/ttya).",
1140 rombug_open,
1141 rombug_close,
1142 0,
1143 rombug_detach,
1144 rombug_resume,
1145 rombug_wait,
1146 rombug_fetch_register,
1147 rombug_store_register,
1148 rombug_prepare_to_store,
1149 rombug_xfer_inferior_memory,
1150 rombug_files_info,
1151 rombug_insert_breakpoint,
1152 rombug_remove_breakpoint, /* Breakpoints */
1153 0,
1154 0,
1155 0,
1156 0,
1157 0, /* Terminal handling */
1158 rombug_kill,
1159 rombug_load, /* load */
d9389f37 1160 rombug_link, /* lookup_symbol */
1340861c
KH
1161 rombug_create_inferior,
1162 rombug_mourn_inferior,
1163 0, /* can_run */
1164 0, /* notice_signals */
78b459a7 1165 0, /* to_stop */
1340861c
KH
1166 process_stratum,
1167 0, /* next */
1168 1,
1169 1,
1170 1,
1171 1,
1172 1, /* has execution */
1173 0,
1174 0, /* Section pointers */
1175 OPS_MAGIC, /* Always the last thing */
1176};
1177
1178void
1179_initialize_remote_os9k ()
1180{
1181 add_target (&rombug_ops);
1182
1183 add_show_from_set (
1184 add_set_cmd ("hash", no_class, var_boolean, (char *)&hashmark,
1185 "Set display of activity while downloading a file.\nWhen enabled, a period \'.\' is displayed.",
1186 &setlist),
1187 &showlist);
1188
1189 add_show_from_set (
1190 add_set_cmd ("timeout", no_class, var_zinteger,
1191 (char *) &timeout,
1192 "Set timeout in seconds for remote MIPS serial I/O.",
1193 &setlist),
1194 &showlist);
1195
d9389f37 1196 add_show_from_set (
d80ff70c 1197 add_set_cmd ("remotelog", no_class, var_zinteger,
d9389f37
KH
1198 (char *) &monitor_log,
1199 "Set monitor activity log on(=1) or off(=0).",
1200 &setlist),
1201 &showlist);
1202
d80ff70c
KH
1203 add_show_from_set (
1204 add_set_cmd ("remotexon", no_class, var_zinteger,
1205 (char *) &tty_xon,
1206 "Set remote tty line XON control",
1207 &setlist),
1208 &showlist);
1209
1210 add_show_from_set (
1211 add_set_cmd ("remotexoff", no_class, var_zinteger,
1212 (char *) &tty_xoff,
1213 "Set remote tty line XOFF control",
1214 &setlist),
1215 &showlist);
1340861c
KH
1216
1217 add_com ("rombug <command>", class_obscure, rombug_command,
1218 "Send a command to the debug monitor.");
1219#if 0
1220 add_com ("connect", class_obscure, connect_command,
1221 "Connect the terminal directly up to a serial based command monitor.\nUse <CR>~. or <CR>~^D to break out.");
1222#endif
1223}