OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-os9k.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.