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