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