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

Subversion Repositories or1k

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

powered by: WebSVN 2.1.0

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