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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [remote-es.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Memory-access and commands for remote es1800 processes, for GDB.
2
   Copyright 1988, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
3
   Free Software Foundation, Inc.
4
 
5
   This file is added to GDB to make it possible to do debugging via an
6
   ES-1800 emulator. The code was originally written by Johan Holmberg
7
   TT/SJ Ericsson Telecom AB and later modified by Johan Henriksson
8
   TT/SJ. It was modified for gdb 4.0 by TX/DK Jan Nordenand by TX/DKG
9
   Harald Johansen.
10
 
11
   This file is part of GDB.
12
 
13
   GDB is free software; you can redistribute it and/or modify
14
   it under the terms of the GNU General Public License as published by
15
   the Free Software Foundation; either version 1, or (at your option)
16
   any later version.
17
 
18
   GDB is distributed in the hope that it will be useful,
19
   but WITHOUT ANY WARRANTY; without even the implied warranty of
20
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
   GNU General Public License for more details.
22
 
23
   You should have received a copy of the GNU General Public License
24
   along with this program; if not, write to the Free Software
25
   Foundation, Inc., 59 Temple Place - Suite 330,
26
   Boston, MA 02111-1307, USA.  */
27
 
28
 
29
/* Emulator communication protocol.
30
   All values are encoded in ascii hex digits.
31
 
32
   Request
33
   Command
34
   Reply
35
   read registers:
36
   DR<cr>
37
   - 0 -    - 1 -    - 2 -    - 3 -      - 4 -    - 5 -    -- 6 -   - 7 -
38
   D = XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX   XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX
39
   A = XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX   XXXXXXXX XXXXXXXX XXXXXXXX
40
   PC = XXXXXX       SSP = XXXXXX    USP = XXXXXX     SR = XXXXXXXX
41
   >
42
   Each byte of register data is described by two hex digits.
43
 
44
   write regs
45
   D0=XXXXXXXX<cr>
46
   >D1=XXXXXXXX<cr>
47
   >D2=XXXXXXXX<cr>
48
   >D3=XXXXXXXX<cr>
49
   >D4=XXXXXXXX<cr>
50
   >D5=XXXXXXXX<cr>
51
   >D6=XXXXXXXX<cr>
52
   >D7=XXXXXXXX<cr>
53
   >A0=XXXXXXXX<cr>
54
   >A1=XXXXXXXX<cr>
55
   >A2=XXXXXXXX<cr>
56
   >A3=XXXXXXXX<cr>
57
   >A4=XXXXXXXX<cr>
58
   >A5=XXXXXXXX<cr>
59
   >A6=XXXXXXXX<cr>
60
   >A7=XXXXXXXX<cr>
61
   >SR=XXXXXXXX<cr>
62
   >PC=XXXXXX<cr>
63
   >
64
   Each byte of register data is described by two hex digits.
65
 
66
   read mem
67
   @.BAA..AA
68
   $FFFFFFXX
69
   >
70
   AA..AA is address, XXXXXXX is the contents
71
 
72
   write mem
73
   @.BAA..AA=$XXXXXXXX
74
   >
75
   AA..AA is address, XXXXXXXX is data
76
 
77
   cont
78
   PC=$AA..AA
79
   >RBK
80
   R>
81
   AA..AA is address to resume. If AA..AA is omitted, resume at same address.
82
 
83
   step
84
   PC=$AA..AA
85
   >STP
86
   R>
87
   AA..AA is address to resume. If AA..AA is omitted, resume at same address.
88
 
89
   kill req
90
   STP
91
   >
92
 */
93
 
94
 
95
#include <stdio.h>
96
#include <signal.h>
97
#include <sys/ioctl.h>
98
#include <sys/file.h>
99
#include <errno.h>
100
#include <ctype.h>
101
#include <setjmp.h>
102
#include <fcntl.h>
103
#include "defs.h"
104
#include "gdb_string.h"
105
#include "frame.h"
106
#include "inferior.h"
107
#include "target.h"
108
#include "command.h"
109
#include "symfile.h"
110
#include "remote-utils.h"
111
#include "gdbcore.h"
112
#include "serial.h"
113
#include "regcache.h"
114
 
115
/* Prototypes for local functions */
116
 
117
static void es1800_child_detach (char *, int);
118
 
119
static void es1800_child_open (char *, int);
120
 
121
static void es1800_transparent (char *, int);
122
 
123
static void es1800_create_inferior (char *, char *, char **);
124
 
125
static void es1800_load (char *, int);
126
 
127
static void es1800_kill (void);
128
 
129
static int verify_break (int);
130
 
131
static int es1800_remove_breakpoint (CORE_ADDR, char *);
132
 
133
static int es1800_insert_breakpoint (CORE_ADDR, char *);
134
 
135
static void es1800_files_info (struct target_ops *);
136
 
137
static int
138
es1800_xfer_inferior_memory (CORE_ADDR, char *, int, int,
139
                             struct mem_attrib *, struct target_ops *);
140
 
141
static void es1800_prepare_to_store (void);
142
 
143
static ptid_t es1800_wait (ptid_t, struct target_waitstatus *);
144
 
145
static void es1800_resume (ptid_t, int, enum target_signal);
146
 
147
static void es1800_detach (char *, int);
148
 
149
static void es1800_attach (char *, int);
150
 
151
static int damn_b (char *);
152
 
153
static void es1800_open (char *, int);
154
 
155
static void es1800_timer (void);
156
 
157
static void es1800_reset (char *);
158
 
159
static void es1800_request_quit (void);
160
 
161
static int readchar (void);
162
 
163
static void expect (char *, int);
164
 
165
static void expect_prompt (void);
166
 
167
static void download (FILE *, int, int);
168
 
169
#if 0
170
static void bfd_copy (bfd *, bfd *);
171
#endif
172
 
173
static void get_break_addr (int, CORE_ADDR *);
174
 
175
static int fromhex (int);
176
 
177
static int tohex (int);
178
 
179
static void es1800_close (int);
180
 
181
static void es1800_fetch_registers (void);
182
 
183
static void es1800_fetch_register (int);
184
 
185
static void es1800_store_register (int);
186
 
187
static void es1800_read_bytes (CORE_ADDR, char *, int);
188
 
189
static void es1800_write_bytes (CORE_ADDR, char *, int);
190
 
191
static void send_with_reply (char *, char *, int);
192
 
193
static void send_command (char *);
194
 
195
static void send (char *);
196
 
197
static void getmessage (char *, int);
198
 
199
static void es1800_mourn_inferior (void);
200
 
201
static void es1800_create_break_insn (char *, int);
202
 
203
static void es1800_init_break (char *, int);
204
 
205
/* Local variables */
206
 
207
/* FIXME: Convert this to use "set remotedebug" instead.  */
208
#define LOG_FILE "es1800.log"
209
#if defined (LOG_FILE)
210
static FILE *log_file;
211
#endif
212
 
213
extern struct target_ops es1800_ops;    /* Forward decl */
214
extern struct target_ops es1800_child_ops;      /* Forward decl */
215
 
216
static int kiodebug;
217
static int timeout = 100;
218
static char *savename;          /* Name of i/o device used */
219
static serial_ttystate es1800_saved_ttystate;
220
static int es1800_fc_save;      /* Save fcntl state */
221
 
222
/* indicates that the emulator uses 32-bit data-adress (68020-mode)
223
   instead of 24-bit (68000 -mode) */
224
 
225
static int m68020;
226
 
227
#define MODE (m68020 ? "M68020" : "M68000" )
228
#define ES1800_BREAK_VEC (0xf)
229
 
230
/* Descriptor for I/O to remote machine.  Initialize it to NULL so that
231
   es1800_open knows that we don't have a file open when the program
232
   starts.  */
233
 
234
static serial_t es1800_desc = NULL;
235
 
236
#define PBUFSIZ 1000
237
#define HDRLEN sizeof("@.BAAAAAAAA=$VV\r")
238
 
239
/* Maximum number of bytes to read/write at once.  The value here
240
   is chosen to fill up a packet.  */
241
 
242
#define MAXBUFBYTES ((PBUFSIZ-150)*16/75 )
243
 
244
static int es1800_break_vec = 0;
245
static char es1800_break_insn[2];
246
static long es1800_break_address;
247
static void (*old_sigint) ();   /* Old signal-handler for sigint */
248
static jmp_buf interrupt;
249
 
250
/* Local signalhandler to allow breaking tranfers or program run.
251
   Rely on global variables: old_sigint(), interrupt */
252
 
253
static void
254
es1800_request_quit (void)
255
{
256
  /* restore original signalhandler */
257
  signal (SIGINT, old_sigint);
258
  longjmp (interrupt, 1);
259
}
260
 
261
 
262
/* Reset emulator.
263
   Sending reset character(octal 32) to emulator.
264
   quit - return to '(esgdb)' prompt or continue        */
265
 
266
static void
267
es1800_reset (char *quit)
268
{
269
  char buf[80];
270
 
271
  if (quit)
272
    {
273
      printf ("\nResetting emulator...  ");
274
    }
275
  strcpy (buf, "\032");
276
  send (buf);
277
  expect_prompt ();
278
  if (quit)
279
    {
280
      error ("done\n");
281
    }
282
}
283
 
284
 
285
/* Open a connection to a remote debugger and push the new target
286
   onto the stack. Check if the emulator is responding and find out
287
   what kind of processor the emulator is connected to.
288
   Initiate the breakpoint handling in the emulator.
289
 
290
   name     - the filename used for communication (ex. '/dev/tta')
291
   from_tty - says whether to be verbose or not */
292
 
293
static void
294
es1800_open (char *name, int from_tty)
295
{
296
  char buf[PBUFSIZ];
297
  char *p;
298
  int i, fcflag;
299
 
300
  m68020 = 0;
301
 
302
  if (!name)                    /* no device name given in target command */
303
    {
304
      error_no_arg ("serial port device name");
305
    }
306
 
307
  target_preopen (from_tty);
308
  es1800_close (0);
309
 
310
  /* open the device and configure it for communication */
311
 
312
#ifndef DEBUG_STDIN
313
 
314
  es1800_desc = SERIAL_OPEN (name);
315
  if (es1800_desc == NULL)
316
    {
317
      perror_with_name (name);
318
    }
319
  savename = savestring (name, strlen (name));
320
 
321
  es1800_saved_ttystate = SERIAL_GET_TTY_STATE (es1800_desc);
322
 
323
  if ((fcflag = fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_GETFL, 0)) == -1)
324
    {
325
      perror_with_name ("fcntl serial");
326
    }
327
  es1800_fc_save = fcflag;
328
 
329
  fcflag = (fcflag & (FREAD | FWRITE));         /* mask out any funny stuff */
330
  if (fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_SETFL, fcflag) == -1)
331
    {
332
      perror_with_name ("fcntl serial");
333
    }
334
 
335
  if (baud_rate != -1)
336
    {
337
      if (SERIAL_SETBAUDRATE (es1800_desc, baud_rate))
338
        {
339
          SERIAL_CLOSE (es1800_desc);
340
          perror_with_name (name);
341
        }
342
    }
343
 
344
  SERIAL_RAW (es1800_desc);
345
 
346
  /* If there is something sitting in the buffer we might take it as a
347
     response to a command, which would be bad.  */
348
  SERIAL_FLUSH_INPUT (es1800_desc);
349
 
350
#endif /* DEBUG_STDIN */
351
 
352
  push_target (&es1800_ops);    /* Switch to using remote target now */
353
  if (from_tty)
354
    {
355
      printf ("Remote ES1800 debugging using %s\n", name);
356
    }
357
 
358
#if defined (LOG_FILE)
359
 
360
  log_file = fopen (LOG_FILE, "w");
361
  if (log_file == NULL)
362
    {
363
      perror_with_name (LOG_FILE);
364
    }
365
 
366
#endif /* LOG_FILE */
367
 
368
  /* Hello?  Are you there?, also check mode  */
369
 
370
  /*  send_with_reply( "DB 0 TO 1", buf, sizeof(buf)); */
371
  /*  for (p = buf, i = 0; *p++ =='0';)  *//* count the number of zeros */
372
  /*      i++; */
373
 
374
  send ("\032");
375
  getmessage (buf, sizeof (buf));       /* send reset character */
376
 
377
  if (from_tty)
378
    {
379
      printf ("Checking mode.... ");
380
    }
381
  /*  m68020 = (i==8); *//* if eight zeros then we are in m68020 mode */
382
 
383
  /* What kind of processor am i talking to ? */
384
  p = buf;
385
  while (*p++ != '\n')
386
    {;
387
    }
388
  while (*p++ != '\n')
389
    {;
390
    }
391
  while (*p++ != '\n')
392
    {;
393
    }
394
  for (i = 0; i < 20; i++, p++)
395
    {;
396
    }
397
  m68020 = !strncmp (p, "68020", 5);
398
  if (from_tty)
399
    {
400
      printf ("You are in %s(%c%c%c%c%c)-mode\n", MODE, p[0], p[1], p[2],
401
              p[3], p[4]);
402
    }
403
 
404
  /* if no init_break statement is present in .gdb file we have to check
405
     whether to download a breakpoint routine or not */
406
 
407
#if 0
408
  if ((es1800_break_vec == 0) || (verify_break (es1800_break_vec) != 0)
409
      && query ("No breakpoint routine in ES 1800 emulator!\nDownload a breakpoint routine to the emulator? "))
410
    {
411
      CORE_ADDR memaddress;
412
      printf ("Give the start address of the breakpoint routine: ");
413
      scanf ("%li", &memaddress);
414
      es1800_init_break ((es1800_break_vec ? es1800_break_vec :
415
                          ES1800_BREAK_VEC), memaddress);
416
    }
417
#endif
418
 
419
}
420
 
421
/*  Close out all files and local state before this target loses control.
422
   quitting - are we quitting gdb now? */
423
 
424
static void
425
es1800_close (int quitting)
426
{
427
  if (es1800_desc != NULL)
428
    {
429
      printf ("\nClosing connection to emulator...\n");
430
      if (SERIAL_SET_TTY_STATE (es1800_desc, es1800_saved_ttystate) < 0)
431
        print_sys_errmsg ("warning: unable to restore tty state", errno);
432
      fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_SETFL, es1800_fc_save);
433
      SERIAL_CLOSE (es1800_desc);
434
      es1800_desc = NULL;
435
    }
436
  if (savename != NULL)
437
    {
438
      xfree (savename);
439
    }
440
  savename = NULL;
441
 
442
#if defined (LOG_FILE)
443
 
444
  if (log_file != NULL)
445
    {
446
      if (ferror (log_file))
447
        {
448
          printf ("Error writing log file.\n");
449
        }
450
      if (fclose (log_file) != 0)
451
        {
452
          printf ("Error closing log file.\n");
453
        }
454
      log_file = NULL;
455
    }
456
 
457
#endif /* LOG_FILE */
458
 
459
}
460
 
461
/*  Attaches to a process on the target side
462
   proc_id  - the id of the process to be attached.
463
   from_tty - says whether to be verbose or not */
464
 
465
static void
466
es1800_attach (char *args, int from_tty)
467
{
468
  error ("Cannot attach to pid %s, this feature is not implemented yet.",
469
         args);
470
}
471
 
472
 
473
/* Takes a program previously attached to and detaches it.
474
   We better not have left any breakpoints
475
   in the program or it'll die when it hits one.
476
   Close the open connection to the remote debugger.
477
   Use this when you want to detach and do something else
478
   with your gdb.
479
 
480
   args     - arguments given to the 'detach' command
481
   from_tty - says whether to be verbose or not */
482
 
483
static void
484
es1800_detach (char *args, int from_tty)
485
{
486
  if (args)
487
    {
488
      error ("Argument given to \"detach\" when remotely debugging.");
489
    }
490
  pop_target ();
491
  if (from_tty)
492
    {
493
      printf ("Ending es1800 remote debugging.\n");
494
    }
495
}
496
 
497
 
498
/* Tell the remote machine to resume.
499
   step    - single-step or run free
500
   siggnal - the signal value to be given to the target (0 = no signal) */
501
 
502
static void
503
es1800_resume (ptid_t ptid, int step, enum target_signal siggnal)
504
{
505
  char buf[PBUFSIZ];
506
 
507
  if (siggnal)
508
    {
509
      error ("Can't send signals to a remote system.");
510
    }
511
  if (step)
512
    {
513
      strcpy (buf, "STP\r");
514
      send (buf);
515
    }
516
  else
517
    {
518
      send_command ("RBK");
519
    }
520
}
521
 
522
/* Wait until the remote machine stops, then return,
523
   storing status in STATUS just as `wait' would.
524
   status -  */
525
 
526
static ptid_t
527
es1800_wait (ptid_t ptid, struct target_waitstatus *status)
528
{
529
  unsigned char buf[PBUFSIZ];
530
  int old_timeout = timeout;
531
 
532
  status->kind = TARGET_WAITKIND_EXITED;
533
  status->value.integer = 0;
534
 
535
  timeout = 0;                   /* Don't time out -- user program is running. */
536
  if (!setjmp (interrupt))
537
    {
538
      old_sigint = signal (SIGINT, es1800_request_quit);
539
      while (1)
540
        {
541
          getmessage (buf, sizeof (buf));
542
          if (strncmp (buf, "\r\n* BREAK *", 11) == 0)
543
            {
544
              status->kind = TARGET_WAITKIND_STOPPED;
545
              status->value.sig = TARGET_SIGNAL_TRAP;
546
              send_command ("STP");     /* Restore stack and PC and such */
547
              if (m68020)
548
                {
549
                  send_command ("STP");
550
                }
551
              break;
552
            }
553
          if (strncmp (buf, "STP\r\n ", 6) == 0)
554
            {
555
              status->kind = TARGET_WAITKIND_STOPPED;
556
              status->value.sig = TARGET_SIGNAL_TRAP;
557
              break;
558
            }
559
          if (buf[strlen (buf) - 2] == 'R')
560
            {
561
              printf ("Unexpected emulator reply: \n%s\n", buf);
562
            }
563
          else
564
            {
565
              printf ("Unexpected stop: \n%s\n", buf);
566
              status->kind = TARGET_WAITKIND_STOPPED;
567
              status->value.sig = TARGET_SIGNAL_QUIT;
568
              break;
569
            }
570
        }
571
    }
572
  else
573
    {
574
      fflush (stdin);
575
      printf ("\nStopping emulator...");
576
      if (!setjmp (interrupt))
577
        {
578
          old_sigint = signal (SIGINT, es1800_request_quit);
579
          send_command ("STP");
580
          printf (" emulator stopped\n");
581
          status->kind = TARGET_WAITKIND_STOPPED;
582
          status->value.sig = TARGET_SIGNAL_INT;
583
        }
584
      else
585
        {
586
          fflush (stdin);
587
          es1800_reset ((char *) 1);
588
        }
589
    }
590
  signal (SIGINT, old_sigint);
591
  timeout = old_timeout;
592
  return inferior_ptid;
593
}
594
 
595
 
596
/* Fetch register values from remote machine.
597
   regno - the register to be fetched (fetch all registers if -1) */
598
 
599
static void
600
es1800_fetch_register (int regno)
601
{
602
  char buf[PBUFSIZ];
603
  int k;
604
  int r;
605
  char *p;
606
  static char regtab[18][4] =
607
  {
608
    "D0 ", "D1 ", "D2 ", "D3 ", "D4 ", "D5 ", "D6 ", "D7 ",
609
    "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", "A6 ", "SSP",
610
    "SR ", "PC "
611
  };
612
 
613
  if ((regno < 15) || (regno == 16) || (regno == 17))
614
    {
615
      r = regno * 4;
616
      send_with_reply (regtab[regno], buf, sizeof (buf));
617
      p = buf;
618
      for (k = 0; k < 4; k++)
619
        {
620
          if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0))
621
            {
622
              error ("Emulator reply is too short: %s", buf);
623
            }
624
          registers[r++] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]);
625
        }
626
    }
627
  else
628
    {
629
      es1800_fetch_registers ();
630
    }
631
}
632
 
633
/* Read the remote registers into REGISTERS.
634
   Always fetches all registers. */
635
 
636
static void
637
es1800_fetch_registers (void)
638
{
639
  char buf[PBUFSIZ];
640
  char SR_buf[PBUFSIZ];
641
  int i;
642
  int k;
643
  int r;
644
  char *p;
645
 
646
  send_with_reply ("DR", buf, sizeof (buf));
647
 
648
  /* Reply is edited to a string that describes registers byte by byte,
649
     each byte encoded as two hex characters.  */
650
 
651
  p = buf;
652
  r = 0;
653
 
654
  /*  parsing row one - D0-D7-registers  */
655
 
656
  while (*p++ != '\n')
657
    {;
658
    }
659
  for (i = 4; i < 70; i += (i == 39 ? 3 : 1))
660
    {
661
      for (k = 0; k < 4; k++)
662
        {
663
          if (p[i + 0] == 0 || p[i + 1] == 0)
664
            {
665
              error ("Emulator reply is too short: %s", buf);
666
            }
667
          registers[r++] = (fromhex (p[i + 0]) * 16) + fromhex (p[i + 1]);
668
          i += 2;
669
        }
670
    }
671
  p += i;
672
 
673
  /*  parsing row two - A0-A6-registers  */
674
 
675
  while (*p++ != '\n')
676
    {;
677
    }
678
  for (i = 4; i < 61; i += (i == 39 ? 3 : 1))
679
    {
680
      for (k = 0; k < 4; k++)
681
        {
682
          if (p[i + 0] == 0 || p[i + 1] == 0)
683
            {
684
              error ("Emulator reply is too short: %s", buf);
685
            }
686
          registers[r++] = (fromhex (p[i + 0])) * 16 + fromhex (p[i + 1]);
687
          i += 2;
688
        }
689
    }
690
  p += i;
691
 
692
  while (*p++ != '\n')
693
    {;
694
    }
695
 
696
  /* fetch SSP-, SR- and PC-registers  */
697
 
698
  /* first - check STATUS-word and decide which stackpointer to use */
699
 
700
  send_with_reply ("SR", SR_buf, sizeof (SR_buf));
701
  p = SR_buf;
702
  p += 5;
703
 
704
  if (m68020)
705
    {
706
      if (*p == '3')            /* use masterstackpointer MSP */
707
        {
708
          send_with_reply ("MSP", buf, sizeof (buf));
709
        }
710
      else if (*p == '2')       /* use interruptstackpointer ISP  */
711
        {
712
          send_with_reply ("ISP", buf, sizeof (buf));
713
        }
714
      else
715
        /* use userstackpointer USP  */
716
        {
717
          send_with_reply ("USP", buf, sizeof (buf));
718
        }
719
      p = buf;
720
      for (k = 0; k < 4; k++)
721
        {
722
          if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
723
            {
724
              error ("Emulator reply is too short: %s", buf);
725
            }
726
          registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]);
727
        }
728
 
729
      p = SR_buf;
730
      for (k = 0; k < 4; k++)
731
        {
732
          if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
733
            {
734
              error ("Emulator reply is too short: %s", buf);
735
            }
736
          registers[r++] =
737
            fromhex (SR_buf[k * 2 + 1]) * 16 + fromhex (SR_buf[k * 2 + 2]);
738
        }
739
      send_with_reply ("PC", buf, sizeof (buf));
740
      p = buf;
741
      for (k = 0; k < 4; k++)
742
        {
743
          if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
744
            {
745
              error ("Emulator reply is too short: %s", buf);
746
            }
747
          registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]);
748
        }
749
    }
750
  else
751
    /* 68000-mode */
752
    {
753
      if (*p == '2')            /* use supervisorstackpointer SSP  */
754
        {
755
          send_with_reply ("SSP", buf, sizeof (buf));
756
        }
757
      else
758
        /* use userstackpointer USP  */
759
        {
760
          send_with_reply ("USP", buf, sizeof (buf));
761
        }
762
 
763
      /* fetch STACKPOINTER */
764
 
765
      p = buf;
766
      for (k = 0; k < 4; k++)
767
        {
768
          if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
769
            {
770
              error ("Emulator reply is too short: %s", buf);
771
            }
772
          registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]);
773
        }
774
 
775
      /* fetch STATUS */
776
 
777
      p = SR_buf;
778
      for (k = 0; k < 4; k++)
779
        {
780
          if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
781
            {
782
              error ("Emulator reply is too short: %s", buf);
783
            }
784
          registers[r++] =
785
            fromhex (SR_buf[k * 2 + 1]) * 16 + fromhex (SR_buf[k * 2 + 2]);
786
        }
787
 
788
      /* fetch PC */
789
 
790
      send_with_reply ("PC", buf, sizeof (buf));
791
      p = buf;
792
      for (k = 0; k < 4; k++)
793
        {
794
          if (p[k * 2 + 1] == 0 || p[k * 2 + 2] == 0)
795
            {
796
              error ("Emulator reply is too short: %s", buf);
797
            }
798
          registers[r++] = fromhex (buf[k * 2 + 1]) * 16 + fromhex (buf[k * 2 + 2]);
799
        }
800
    }
801
}
802
 
803
/* Store register value, located in REGISTER, on the target processor.
804
   regno - the register-number of the register to store
805
   (-1 means store them all)
806
   FIXME: Return errno value.  */
807
 
808
static void
809
es1800_store_register (int regno)
810
{
811
 
812
  static char regtab[18][4] =
813
  {
814
    "D0 ", "D1 ", "D2 ", "D3 ", "D4 ", "D5 ", "D6 ", "D7 ",
815
    "A0 ", "A1 ", "A2 ", "A3 ", "A4 ", "A5 ", "A6 ", "SSP",
816
    "SR ", "PC "
817
  };
818
 
819
  char buf[PBUFSIZ];
820
  char SR_buf[PBUFSIZ];
821
  char stack_pointer[4];
822
  char *p;
823
  int i;
824
  int j;
825
  int k;
826
  unsigned char *r;
827
 
828
  r = (unsigned char *) registers;
829
 
830
  if (regno == -1)              /* write all registers */
831
    {
832
      j = 0;
833
      k = 18;
834
    }
835
  else
836
    /* write one register */
837
    {
838
      j = regno;
839
      k = regno + 1;
840
      r += regno * 4;
841
    }
842
 
843
  if ((regno == -1) || (regno == 15))
844
    {
845
      /* fetch current status */
846
      send_with_reply ("SR", SR_buf, sizeof (SR_buf));
847
      p = SR_buf;
848
      p += 5;
849
      if (m68020)
850
        {
851
          if (*p == '3')        /* use masterstackpointer MSP */
852
            {
853
              strcpy (stack_pointer, "MSP");
854
            }
855
          else
856
            {
857
              if (*p == '2')    /* use interruptstackpointer ISP  */
858
                {
859
                  strcpy (stack_pointer, "ISP");
860
                }
861
              else
862
                {
863
                  strcpy (stack_pointer, "USP");        /* use userstackpointer USP  */
864
                }
865
            }
866
        }
867
      else
868
        /* 68000-mode */
869
        {
870
          if (*p == '2')        /* use supervisorstackpointer SSP  */
871
            {
872
              strcpy (stack_pointer, "SSP");
873
            }
874
          else
875
            {
876
              strcpy (stack_pointer, "USP");    /* use userstackpointer USP  */
877
            }
878
        }
879
      strcpy (regtab[15], stack_pointer);
880
    }
881
 
882
  for (i = j; i < k; i++)
883
    {
884
      buf[0] = regtab[i][0];
885
      buf[1] = regtab[i][1];
886
      buf[2] = regtab[i][2];
887
      buf[3] = '=';
888
      buf[4] = '$';
889
      buf[5] = tohex ((*r >> 4) & 0x0f);
890
      buf[6] = tohex (*r++ & 0x0f);
891
      buf[7] = tohex ((*r >> 4) & 0x0f);
892
      buf[8] = tohex (*r++ & 0x0f);
893
      buf[9] = tohex ((*r >> 4) & 0x0f);
894
      buf[10] = tohex (*r++ & 0x0f);
895
      buf[11] = tohex ((*r >> 4) & 0x0f);
896
      buf[12] = tohex (*r++ & 0x0f);
897
      buf[13] = 0;
898
 
899
      send_with_reply (buf, buf, sizeof (buf));         /* FIXME, reply not used? */
900
    }
901
}
902
 
903
 
904
/* Prepare to store registers.  */
905
 
906
static void
907
es1800_prepare_to_store (void)
908
{
909
  /* Do nothing, since we can store individual regs */
910
}
911
 
912
/* Convert hex digit A to a number.  */
913
 
914
static int
915
fromhex (int a)
916
{
917
  if (a >= '0' && a <= '9')
918
    {
919
      return a - '0';
920
    }
921
  else if (a >= 'a' && a <= 'f')
922
    {
923
      return a - 'a' + 10;
924
    }
925
  else if (a >= 'A' && a <= 'F')
926
    {
927
      return a - 'A' + 10;
928
    }
929
  else
930
    {
931
      error ("Reply contains invalid hex digit");
932
    }
933
  return (-1);
934
}
935
 
936
 
937
/* Convert number NIB to a hex digit.  */
938
 
939
static int
940
tohex (int nib)
941
{
942
  if (nib < 10)
943
    {
944
      return ('0' + nib);
945
    }
946
  else
947
    {
948
      return ('A' + nib - 10);
949
    }
950
}
951
 
952
/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
953
   to or from debugger address MYADDR.  Write to inferior if WRITE is
954
   nonzero.  Returns length of data written or read; 0 for error.
955
 
956
   memaddr - the target's address
957
   myaddr  - gdb's address
958
   len     - number of bytes
959
   write   - write if != 0 otherwise read
960
   tops    - unused */
961
 
962
static int
963
es1800_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
964
                             int write,
965
                             struct mem_attrib *attrib ATTRIBUTE_UNUSED,
966
                             struct target_ops *target ATTRIBUTE_UNUSED)
967
{
968
  int origlen = len;
969
  int xfersize;
970
 
971
  while (len > 0)
972
    {
973
      xfersize = len > MAXBUFBYTES ? MAXBUFBYTES : len;
974
      if (write)
975
        {
976
          es1800_write_bytes (memaddr, myaddr, xfersize);
977
        }
978
      else
979
        {
980
          es1800_read_bytes (memaddr, myaddr, xfersize);
981
        }
982
      memaddr += xfersize;
983
      myaddr += xfersize;
984
      len -= xfersize;
985
    }
986
  return (origlen);             /* no error possible */
987
}
988
 
989
 
990
/* Write memory data directly to the emulator.
991
   This does not inform the data cache; the data cache uses this.
992
   MEMADDR is the address in the remote memory space.
993
   MYADDR is the address of the buffer in our space.
994
   LEN is the number of bytes.
995
 
996
   memaddr - the target's address
997
   myaddr  - gdb's address
998
   len     - number of bytes   */
999
 
1000
static void
1001
es1800_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
1002
{
1003
  char buf[PBUFSIZ];
1004
  int i;
1005
  char *p;
1006
 
1007
  p = myaddr;
1008
  for (i = 0; i < len; i++)
1009
    {
1010
      sprintf (buf, "@.B$%x=$%x", memaddr + i, (*p++) & 0xff);
1011
      send_with_reply (buf, buf, sizeof (buf));         /* FIXME send_command? */
1012
    }
1013
}
1014
 
1015
 
1016
/* Read memory data directly from the emulator.
1017
   This does not use the data cache; the data cache uses this.
1018
 
1019
   memaddr - the target's address
1020
   myaddr  - gdb's address
1021
   len     - number of bytes   */
1022
 
1023
static void
1024
es1800_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
1025
{
1026
  static int DB_tab[16] =
1027
  {8, 11, 14, 17, 20, 23, 26, 29, 34, 37, 40, 43, 46, 49, 52, 55};
1028
  char buf[PBUFSIZ];
1029
  int i;
1030
  int low_addr;
1031
  char *p;
1032
  char *b;
1033
 
1034
  if (len > PBUFSIZ / 2 - 1)
1035
    {
1036
      internal_error (__FILE__, __LINE__, "failed internal consistency check");
1037
    }
1038
 
1039
  if (len == 1)                 /* The emulator does not like expressions like:  */
1040
    {
1041
      len = 2;                  /* DB.B $20018 TO $20018                       */
1042
    }
1043
 
1044
  /* Reply describes registers byte by byte, each byte encoded as two hex
1045
     characters.  */
1046
 
1047
  sprintf (buf, "DB.B $%x TO $%x", memaddr, memaddr + len - 1);
1048
  send_with_reply (buf, buf, sizeof (buf));
1049
  b = buf;
1050
  low_addr = memaddr & 0x0f;
1051
  for (i = low_addr; i < low_addr + len; i++)
1052
    {
1053
      if ((!(i % 16)) && i)
1054
        {                       /* if (i = 16,32,48)  */
1055
          while (*p++ != '\n')
1056
            {;
1057
            }
1058
          b = p;
1059
        }
1060
      p = b + DB_tab[i % 16] + (m68020 ? 2 : 0);
1061
      if (p[0] == 32 || p[1] == 32)
1062
        {
1063
          error ("Emulator reply is too short: %s", buf);
1064
        }
1065
      myaddr[i - low_addr] = fromhex (p[0]) * 16 + fromhex (p[1]);
1066
    }
1067
}
1068
 
1069
/* Display information about the current target.  TOPS is unused.  */
1070
 
1071
static void
1072
es1800_files_info (struct target_ops *tops)
1073
{
1074
  printf ("ES1800 Attached to %s at %d baud in %s mode\n", savename, 19200,
1075
          MODE);
1076
}
1077
 
1078
 
1079
/* We read the contents of the target location and stash it,
1080
   then overwrite it with a breakpoint instruction.
1081
 
1082
   addr           - is the target location in the target machine.
1083
   contents_cache - is a pointer to memory allocated for saving the target contents.
1084
   It is guaranteed by the caller to be long enough to save sizeof
1085
   BREAKPOINT bytes.
1086
 
1087
   FIXME: This size is target_arch dependent and should be available in
1088
   the target_arch transfer vector, if we ever have one...  */
1089
 
1090
static int
1091
es1800_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
1092
{
1093
  int val;
1094
 
1095
  val = target_read_memory (addr, contents_cache, sizeof (es1800_break_insn));
1096
 
1097
  if (val == 0)
1098
    {
1099
      val = target_write_memory (addr, es1800_break_insn,
1100
                                 sizeof (es1800_break_insn));
1101
    }
1102
 
1103
  return (val);
1104
}
1105
 
1106
 
1107
/* Write back the stashed instruction
1108
 
1109
   addr           - is the target location in the target machine.
1110
   contents_cache - is a pointer to memory allocated for saving the target contents.
1111
   It is guaranteed by the caller to be long enough to save sizeof
1112
   BREAKPOINT bytes.    */
1113
 
1114
static int
1115
es1800_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
1116
{
1117
 
1118
  return (target_write_memory (addr, contents_cache,
1119
                               sizeof (es1800_break_insn)));
1120
}
1121
 
1122
/* create_break_insn ()
1123
   Primitive datastructures containing the es1800 breakpoint instruction  */
1124
 
1125
static void
1126
es1800_create_break_insn (char *ins, int vec)
1127
{
1128
  if (vec == 15)
1129
    {
1130
      ins[0] = 0x4e;
1131
      ins[1] = 0x4f;
1132
    }
1133
}
1134
 
1135
 
1136
/* verify_break ()
1137
   Seach for breakpoint routine in emulator memory.
1138
   returns non-zero on failure
1139
   vec - trap vector used for breakpoints  */
1140
 
1141
static int
1142
verify_break (int vec)
1143
{
1144
  CORE_ADDR memaddress;
1145
  char buf[8];
1146
  char *instr = "NqNqNqNs";     /* breakpoint routine */
1147
  int status;
1148
 
1149
  get_break_addr (vec, &memaddress);
1150
 
1151
  if (memaddress)
1152
    {
1153
      status = target_read_memory (memaddress, buf, 8);
1154
      if (status != 0)
1155
        {
1156
          memory_error (status, memaddress);
1157
        }
1158
      return (strcmp (instr, buf));
1159
    }
1160
  return (-1);
1161
}
1162
 
1163
 
1164
/* get_break_addr ()
1165
   find address of breakpoint routine
1166
   vec - trap vector used for breakpoints
1167
   addrp - store the address here       */
1168
 
1169
static void
1170
get_break_addr (int vec, CORE_ADDR *addrp)
1171
{
1172
  CORE_ADDR memaddress = 0;
1173
  int status;
1174
  int k;
1175
  char buf[PBUFSIZ];
1176
  char base_addr[4];
1177
  char *p;
1178
 
1179
  if (m68020)
1180
    {
1181
      send_with_reply ("VBR ", buf, sizeof (buf));
1182
      p = buf;
1183
      for (k = 0; k < 4; k++)
1184
        {
1185
          if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0))
1186
            {
1187
              error ("Emulator reply is too short: %s", buf);
1188
            }
1189
          base_addr[k] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]);
1190
        }
1191
      /* base addr of exception vector table */
1192
      memaddress = *((CORE_ADDR *) base_addr);
1193
    }
1194
 
1195
  memaddress += (vec + 32) * 4; /* address of trap vector */
1196
  status = target_read_memory (memaddress, (char *) addrp, 4);
1197
  if (status != 0)
1198
    {
1199
      memory_error (status, memaddress);
1200
    }
1201
}
1202
 
1203
 
1204
/* Kill an inferior process */
1205
 
1206
static void
1207
es1800_kill (void)
1208
{
1209
  if (!ptid_equal (inferior_ptid, null_ptid))
1210
    {
1211
      inferior_ptid = null_ptid;
1212
      es1800_mourn_inferior ();
1213
    }
1214
}
1215
 
1216
 
1217
/* Load a file to the ES1800 emulator.
1218
   Converts the file from a.out format into Extended Tekhex format
1219
   before the file is loaded.
1220
   Also loads the trap routine, and sets the ES1800 breakpoint on it
1221
   filename - the a.out to be loaded
1222
   from_tty - says whether to be verbose or not
1223
   FIXME Uses emulator overlay memory for trap routine  */
1224
 
1225
static void
1226
es1800_load (char *filename, int from_tty)
1227
{
1228
 
1229
  FILE *instream;
1230
  char loadname[15];
1231
  char buf[160];
1232
  struct cleanup *old_chain;
1233
  int es1800_load_format = 5;
1234
 
1235
  if (es1800_desc == NULL)
1236
    {
1237
      printf ("No emulator attached, type emulator-command first\n");
1238
      return;
1239
    }
1240
 
1241
  filename = tilde_expand (filename);
1242
  make_cleanup (xfree, filename);
1243
 
1244
  switch (es1800_load_format)
1245
    {
1246
    case 2:                     /* Extended Tekhex  */
1247
      if (from_tty)
1248
        {
1249
          printf ("Converting \"%s\" to Extended Tekhex Format\n", filename);
1250
        }
1251
      sprintf (buf, "tekhex %s", filename);
1252
      system (buf);
1253
      sprintf (loadname, "out.hex");
1254
      break;
1255
 
1256
    case 5:                     /* Motorola S-rec  */
1257
      if (from_tty)
1258
        {
1259
          printf ("Converting \"%s\" to Motorola S-record format\n",
1260
                  filename);
1261
        }
1262
      /* in the future the source code in copy (part of binutils-1.93) will
1263
         be included in this file */
1264
      sprintf (buf,
1265
               "copy -s \"a.out-sunos-big\" -d \"srec\" %s /tmp/out.hex",
1266
               filename);
1267
      system (buf);
1268
      sprintf (loadname, "/tmp/out.hex");
1269
      break;
1270
 
1271
    default:
1272
      error ("Downloading format not defined\n");
1273
    }
1274
 
1275
  breakpoint_init_inferior ();
1276
  inferior_ptid = null_ptid;
1277
  if (from_tty)
1278
    {
1279
      printf ("Downloading \"%s\" to the ES 1800\n", filename);
1280
    }
1281
  if ((instream = fopen (loadname, "r")) == NULL)
1282
    {
1283
      perror_with_name ("fopen:");
1284
    }
1285
 
1286
  old_chain = make_cleanup (fclose, instream);
1287
  immediate_quit++;
1288
 
1289
  es1800_reset (0);
1290
 
1291
  download (instream, from_tty, es1800_load_format);
1292
 
1293
  /* if breakpoint routine is not present anymore we have to check
1294
     whether to download a new breakpoint routine or not */
1295
 
1296
  if ((verify_break (es1800_break_vec) != 0)
1297
      && query ("No breakpoint routine in ES 1800 emulator!\nDownload a breakpoint routine to the emulator? "))
1298
    {
1299
      char buf[128];
1300
      printf ("Using break vector 0x%x\n", es1800_break_vec);
1301
      sprintf (buf, "0x%x ", es1800_break_vec);
1302
      printf ("Give the start address of the breakpoint routine: ");
1303
      fgets (buf + strlen (buf), sizeof (buf) - strlen (buf), stdin);
1304
      es1800_init_break (buf, 0);
1305
    }
1306
 
1307
  do_cleanups (old_chain);
1308
  expect_prompt ();
1309
  readchar ();                  /* FIXME I am getting a ^G = 7 after the prompt  */
1310
  printf ("\n");
1311
 
1312
  if (fclose (instream) == EOF)
1313
    {
1314
      ;
1315
    }
1316
 
1317
  if (es1800_load_format != 2)
1318
    {
1319
      sprintf (buf, "/usr/bin/rm %s", loadname);
1320
      system (buf);
1321
    }
1322
 
1323
  symbol_file_add_main (filename, from_tty);    /* reading symbol table */
1324
  immediate_quit--;
1325
}
1326
 
1327
#if 0
1328
 
1329
#define NUMCPYBYTES 20
1330
 
1331
static void
1332
bfd_copy (bfd *from_bfd, bfd *to_bfd)
1333
{
1334
  asection *p, *new;
1335
  int i;
1336
  char buf[NUMCPYBYTES];
1337
 
1338
  for (p = from_bfd->sections; p != NULL; p = p->next)
1339
    {
1340
      printf ("  Copying section %s. Size = %x.\n", p->name, p->_cooked_size);
1341
      printf ("    vma = %x,  offset = %x,  output_sec = %x\n",
1342
              p->vma, p->output_offset, p->output_section);
1343
      new = bfd_make_section (to_bfd, p->name);
1344
      if (p->_cooked_size &&
1345
          !bfd_set_section_size (to_bfd, new, p->_cooked_size))
1346
        {
1347
          error ("Wrong BFD size!\n");
1348
        }
1349
      if (!bfd_set_section_flags (to_bfd, new, p->flags))
1350
        {
1351
          error ("bfd_set_section_flags");
1352
        }
1353
      new->vma = p->vma;
1354
 
1355
      for (i = 0; (i + NUMCPYBYTES) < p->_cooked_size; i += NUMCPYBYTES)
1356
        {
1357
          if (!bfd_get_section_contents (from_bfd, p, (PTR) buf, (file_ptr) i,
1358
                                         (bfd_size_type) NUMCPYBYTES))
1359
            {
1360
              error ("bfd_get_section_contents\n");
1361
            }
1362
          if (!bfd_set_section_contents (to_bfd, new, (PTR) buf, (file_ptr) i,
1363
                                         (bfd_size_type) NUMCPYBYTES))
1364
            {
1365
              error ("bfd_set_section_contents\n");
1366
            }
1367
        }
1368
      bfd_get_section_contents (from_bfd, p, (PTR) buf, (file_ptr) i,
1369
                                (bfd_size_type) (p->_cooked_size - i));
1370
      bfd_set_section_contents (to_bfd, new, (PTR) buf, (file_ptr) i,
1371
                                (bfd_size_type) (p->_cooked_size - i));
1372
    }
1373
}
1374
 
1375
#endif
1376
 
1377
/* Start an process on the es1800 and set inferior_ptid to the new
1378
   process' pid.
1379
   execfile - the file to run
1380
   args     - arguments passed to the program
1381
   env      - the environment vector to pass    */
1382
 
1383
static void
1384
es1800_create_inferior (char *execfile, char *args, char **env)
1385
{
1386
  int entry_pt;
1387
  int pid;
1388
#if 0
1389
  struct expression *expr;
1390
  register struct cleanup *old_chain = 0;
1391
  register value val;
1392
#endif
1393
 
1394
  if (args && *args)
1395
    {
1396
      error ("Can't pass arguments to remote ES1800 process");
1397
    }
1398
 
1399
#if 0
1400
  if (query ("Use 'start' as entry point? "))
1401
    {
1402
      expr = parse_c_expression ("start");
1403
      old_chain = make_cleanup (free_current_contents, &expr);
1404
      val = evaluate_expression (expr);
1405
      entry_pt = (val->location).address;
1406
    }
1407
  else
1408
    {
1409
      printf ("Enter the program's entry point (in hexadecimal): ");
1410
      scanf ("%x", &entry_pt);
1411
    }
1412
#endif
1413
 
1414
  if (execfile == 0 || exec_bfd == 0)
1415
    {
1416
      error ("No executable file specified");
1417
    }
1418
 
1419
  entry_pt = (int) bfd_get_start_address (exec_bfd);
1420
 
1421
  pid = 42;
1422
 
1423
  /* Now that we have a child process, make it our target.  */
1424
 
1425
  push_target (&es1800_child_ops);
1426
 
1427
  /* The "process" (board) is already stopped awaiting our commands, and
1428
     the program is already downloaded.  We just set its PC and go.  */
1429
 
1430
  inferior_ptid = pid_to_ptid (pid);    /* Needed for wait_for_inferior below */
1431
 
1432
  clear_proceed_status ();
1433
 
1434
  /* Tell wait_for_inferior that we've started a new process.  */
1435
 
1436
  init_wait_for_inferior ();
1437
 
1438
  /* Set up the "saved terminal modes" of the inferior
1439
     based on what modes we are starting it with.  */
1440
 
1441
  target_terminal_init ();
1442
 
1443
  /* Install inferior's terminal modes.  */
1444
 
1445
  target_terminal_inferior ();
1446
 
1447
  /* remote_start (args); */
1448
  /* trap_expected = 0; */
1449
  /* insert_step_breakpoint ();  FIXME, do we need this?  */
1450
 
1451
  /* Let 'er rip... */
1452
  proceed ((CORE_ADDR) entry_pt, TARGET_SIGNAL_DEFAULT, 0);
1453
 
1454
}
1455
 
1456
 
1457
/* The process has died, clean up.  */
1458
 
1459
static void
1460
es1800_mourn_inferior (void)
1461
{
1462
  remove_breakpoints ();
1463
  unpush_target (&es1800_child_ops);
1464
  generic_mourn_inferior ();    /* Do all the proper things now */
1465
}
1466
 
1467
/* ES1800-protocol specific routines */
1468
 
1469
/* Keep discarding input from the remote system, until STRING is found.
1470
   Let the user break out immediately.
1471
   string - the string to expect
1472
   nowait - break out if string not the emulator's first respond otherwise
1473
   read until string is found (== 0)   */
1474
 
1475
static void
1476
expect (char *string, int nowait)
1477
{
1478
  char c;
1479
  char *p = string;
1480
 
1481
  immediate_quit++;
1482
  while (1)
1483
    {
1484
      c = readchar ();
1485
      if (isalpha (c))
1486
        {
1487
          c = toupper (c);
1488
        }
1489
      if (c == toupper (*p))
1490
        {
1491
          p++;
1492
          if (*p == '\0')
1493
            {
1494
              immediate_quit--;
1495
              return;
1496
            }
1497
        }
1498
      else if (!nowait)
1499
        {
1500
          p = string;
1501
        }
1502
      else
1503
        {
1504
          printf ("\'%s\' expected\n", string);
1505
          printf ("char %d is %d", p - string, c);
1506
          error ("\n");
1507
        }
1508
    }
1509
}
1510
 
1511
/* Keep discarding input until we see the prompt.  */
1512
 
1513
static void
1514
expect_prompt (void)
1515
{
1516
  expect (">", 0);
1517
}
1518
 
1519
 
1520
/* Read one character */
1521
 
1522
#ifdef DEBUG_STDIN
1523
 
1524
/* read from stdin */
1525
 
1526
static int
1527
readchar (void)
1528
{
1529
  char buf[1];
1530
 
1531
  buf[0] = '\0';
1532
  printf ("readchar, give one character\n");
1533
  read (0, buf, 1);
1534
 
1535
#if defined (LOG_FILE)
1536
  putc (buf[0] & 0x7f, log_file);
1537
#endif
1538
 
1539
  return (buf[0] & 0x7f);
1540
}
1541
 
1542
#else /* !DEBUG_STDIN */
1543
 
1544
/* Read a character from the remote system, doing all the fancy
1545
   timeout stuff.  */
1546
 
1547
static int
1548
readchar (void)
1549
{
1550
  int ch;
1551
 
1552
  ch = SERIAL_READCHAR (es1800_desc, timeout);
1553
 
1554
  /* FIXME: doing an error() here will probably cause trouble, at least if from
1555
     es1800_wait.  */
1556
  if (ch == SERIAL_TIMEOUT)
1557
    error ("Timeout reading from remote system.");
1558
  else if (ch == SERIAL_ERROR)
1559
    perror_with_name ("remote read");
1560
 
1561
#if defined (LOG_FILE)
1562
  putc (ch & 0x7f, log_file);
1563
  fflush (log_file);
1564
#endif
1565
 
1566
  return (ch);
1567
}
1568
 
1569
#endif /* DEBUG_STDIN */
1570
 
1571
 
1572
/* Send a command to the emulator and save the reply.
1573
   Report an error if we get an error reply.
1574
   string - the es1800 command
1575
   buf    - containing the emulator reply on return
1576
   len    - size of buf  */
1577
 
1578
static void
1579
send_with_reply (char *string, char *buf, int len)
1580
{
1581
  send (string);
1582
  SERIAL_WRITE (es1800_desc, "\r", 1);
1583
 
1584
#ifndef DEBUG_STDIN
1585
  expect (string, 1);
1586
  expect ("\r\n", 0);
1587
#endif
1588
 
1589
  getmessage (buf, len);
1590
}
1591
 
1592
 
1593
/* Send the command in STR to the emulator adding \r. check
1594
   the echo for consistency.
1595
   string - the es1800 command  */
1596
 
1597
static void
1598
send_command (char *string)
1599
{
1600
  send (string);
1601
  SERIAL_WRITE (es1800_desc, "\r", 1);
1602
 
1603
#ifndef DEBUG_STDIN
1604
  expect (string, 0);
1605
  expect_prompt ();
1606
#endif
1607
 
1608
}
1609
 
1610
/* Send a string
1611
   string - the es1800 command  */
1612
 
1613
static void
1614
send (char *string)
1615
{
1616
  if (kiodebug)
1617
    {
1618
      fprintf (stderr, "Sending: %s\n", string);
1619
    }
1620
  SERIAL_WRITE (es1800_desc, string, strlen (string));
1621
}
1622
 
1623
 
1624
/* Read a message from the emulator and store it in BUF.
1625
   buf    - containing the emulator reply on return
1626
   len    - size of buf  */
1627
 
1628
static void
1629
getmessage (char *buf, int len)
1630
{
1631
  char *bp;
1632
  int c;
1633
  int prompt_found = 0;
1634
  extern kiodebug;
1635
 
1636
#if defined (LOG_FILE)
1637
  /* This is a convenient place to do this.  The idea is to do it often
1638
     enough that we never lose much data if we terminate abnormally.  */
1639
  fflush (log_file);
1640
#endif
1641
 
1642
  bp = buf;
1643
  c = readchar ();
1644
  do
1645
    {
1646
      if (c)
1647
        {
1648
          if (len-- < 2)        /* char and terminaling NULL */
1649
            {
1650
              error ("input buffer overrun\n");
1651
            }
1652
          *bp++ = c;
1653
        }
1654
      c = readchar ();
1655
      if ((c == '>') && (*(bp - 1) == ' '))
1656
        {
1657
          prompt_found = 1;
1658
        }
1659
    }
1660
  while (!prompt_found);
1661
  *bp = 0;
1662
 
1663
  if (kiodebug)
1664
    {
1665
      fprintf (stderr, "message received :%s\n", buf);
1666
    }
1667
}
1668
 
1669
static void
1670
download (FILE *instream, int from_tty, int format)
1671
{
1672
  char c;
1673
  char buf[160];
1674
  int i = 0;
1675
 
1676
  send_command ("SET #2,$1A");  /* reset char = ^Z */
1677
  send_command ("SET #3,$11,$13");      /* XON  XOFF */
1678
  if (format == 2)
1679
    {
1680
      send_command ("SET #26,#2");
1681
    }
1682
  else
1683
    {
1684
      send_command ("SET #26,#5");      /* Format=Extended Tekhex */
1685
    }
1686
  send_command ("DFB = $10");
1687
  send_command ("PUR");
1688
  send_command ("CES");
1689
  send ("DNL\r");
1690
  expect ("DNL", 1);
1691
  if (from_tty)
1692
    {
1693
      printf ("    0 records loaded...\r");
1694
    }
1695
  while (fgets (buf, 160, instream))
1696
    {
1697
      send (buf);
1698
      if (from_tty)
1699
        {
1700
          printf ("%5d\b\b\b\b\b", ++i);
1701
          fflush (stdout);
1702
        }
1703
      if ((c = readchar ()) != 006)
1704
        {
1705
          error ("expected ACK");
1706
        }
1707
    }
1708
  if (from_tty)
1709
    {
1710
      printf ("- All");
1711
    }
1712
}
1713
 
1714
/* Additional commands */
1715
 
1716
#if defined (TIOCGETP) && defined (FNDELAY) && defined (EWOULDBLOCK)
1717
#define PROVIDE_TRANSPARENT
1718
#endif
1719
 
1720
#ifdef PROVIDE_TRANSPARENT
1721
/* Talk directly to the emulator
1722
   FIXME, uses busy wait, and is SUNOS (or at least BSD) specific  */
1723
 
1724
/*ARGSUSED */
1725
static void
1726
es1800_transparent (char *args, int from_tty)
1727
{
1728
  int console;
1729
  struct sgttyb modebl;
1730
  int fcflag;
1731
  int cc;
1732
  struct sgttyb console_mode_save;
1733
  int console_fc_save;
1734
  int es1800_fc_save;
1735
  int inputcnt = 80;
1736
  char inputbuf[80];
1737
  int consolecnt = 0;
1738
  char consolebuf[80];
1739
  int es1800_cnt = 0;
1740
  char es1800_buf[80];
1741
  int i;
1742
 
1743
  dont_repeat ();
1744
  if (es1800_desc == NULL)
1745
    {
1746
      printf ("No emulator attached, type emulator-command first\n");
1747
      return;
1748
    }
1749
 
1750
  printf ("\n");
1751
  printf ("You are now communicating directly with the ES 1800 emulator.\n");
1752
  printf ("To leave this mode (transparent mode), press ^E.\n");
1753
  printf ("\n");
1754
  printf (" >");
1755
  fflush (stdout);
1756
 
1757
  if ((console = open ("/dev/tty", O_RDWR)) == -1)
1758
    {
1759
      perror_with_name ("/dev/tty:");
1760
    }
1761
 
1762
  if ((fcflag = fcntl (console, F_GETFL, 0)) == -1)
1763
    {
1764
      perror_with_name ("fcntl console");
1765
    }
1766
 
1767
  console_fc_save = fcflag;
1768
  fcflag = fcflag | FNDELAY;
1769
 
1770
  if (fcntl (console, F_SETFL, fcflag) == -1)
1771
    {
1772
      perror_with_name ("fcntl console");
1773
    }
1774
 
1775
  if (ioctl (console, TIOCGETP, &modebl))
1776
    {
1777
      perror_with_name ("ioctl console");
1778
    }
1779
 
1780
  console_mode_save = modebl;
1781
  modebl.sg_flags = RAW;
1782
 
1783
  if (ioctl (console, TIOCSETP, &modebl))
1784
    {
1785
      perror_with_name ("ioctl console");
1786
    }
1787
 
1788
  if ((fcflag = fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_GETFL, 0)) == -1)
1789
    {
1790
      perror_with_name ("fcntl serial");
1791
    }
1792
 
1793
  es1800_fc_save = fcflag;
1794
  fcflag = fcflag | FNDELAY;
1795
 
1796
  if (fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_SETFL, fcflag) == -1)
1797
    {
1798
      perror_with_name ("fcntl serial");
1799
    }
1800
 
1801
  while (1)
1802
    {
1803
      cc = read (console, inputbuf, inputcnt);
1804
      if (cc != -1)
1805
        {
1806
          if ((*inputbuf & 0x7f) == 0x05)
1807
            {
1808
              break;
1809
            }
1810
          for (i = 0; i < cc;)
1811
            {
1812
              es1800_buf[es1800_cnt++] = inputbuf[i++];
1813
            }
1814
          if ((cc = SERIAL_WRITE (es1800_desc, es1800_buf, es1800_cnt)) == -1)
1815
            {
1816
              perror_with_name ("FEL! write:");
1817
            }
1818
          es1800_cnt -= cc;
1819
          if (es1800_cnt && cc)
1820
            {
1821
              for (i = 0; i < es1800_cnt; i++)
1822
                {
1823
                  es1800_buf[i] = es1800_buf[cc + i];
1824
                }
1825
            }
1826
        }
1827
      else if (errno != EWOULDBLOCK)
1828
        {
1829
          perror_with_name ("FEL! read:");
1830
        }
1831
 
1832
      cc = read (DEPRECATED_SERIAL_FD (es1800_desc), inputbuf, inputcnt);
1833
      if (cc != -1)
1834
        {
1835
          for (i = 0; i < cc;)
1836
            {
1837
              consolebuf[consolecnt++] = inputbuf[i++];
1838
            }
1839
          if ((cc = write (console, consolebuf, consolecnt)) == -1)
1840
            {
1841
              perror_with_name ("FEL! write:");
1842
            }
1843
          consolecnt -= cc;
1844
          if (consolecnt && cc)
1845
            {
1846
              for (i = 0; i < consolecnt; i++)
1847
                {
1848
                  consolebuf[i] = consolebuf[cc + i];
1849
                }
1850
            }
1851
        }
1852
      else if (errno != EWOULDBLOCK)
1853
        {
1854
          perror_with_name ("FEL! read:");
1855
        }
1856
    }
1857
 
1858
  console_fc_save = console_fc_save & !FNDELAY;
1859
  if (fcntl (console, F_SETFL, console_fc_save) == -1)
1860
    {
1861
      perror_with_name ("FEL! fcntl");
1862
    }
1863
 
1864
  if (ioctl (console, TIOCSETP, &console_mode_save))
1865
    {
1866
      perror_with_name ("FEL! ioctl");
1867
    }
1868
 
1869
  close (console);
1870
 
1871
  if (fcntl (DEPRECATED_SERIAL_FD (es1800_desc), F_SETFL, es1800_fc_save) == -1)
1872
    {
1873
      perror_with_name ("FEL! fcntl");
1874
    }
1875
 
1876
  printf ("\n");
1877
 
1878
}
1879
#endif /* PROVIDE_TRANSPARENT */
1880
 
1881
static void
1882
es1800_init_break (char *args, int from_tty)
1883
{
1884
  CORE_ADDR memaddress = 0;
1885
  char buf[PBUFSIZ];
1886
  char base_addr[4];
1887
  char *space_index;
1888
  char *p;
1889
  int k;
1890
 
1891
  if (args == NULL)
1892
    {
1893
      error_no_arg ("a trap vector");
1894
    }
1895
 
1896
  if (!(space_index = strchr (args, ' ')))
1897
    {
1898
      error ("Two arguments needed (trap vector and address of break routine).\n");
1899
    }
1900
 
1901
  *space_index = '\0';
1902
 
1903
  es1800_break_vec = strtol (args, (char **) NULL, 0);
1904
  es1800_break_address = parse_and_eval_address (space_index + 1);
1905
 
1906
  es1800_create_break_insn (es1800_break_insn, es1800_break_vec);
1907
 
1908
  if (m68020)
1909
    {
1910
      send_with_reply ("VBR ", buf, sizeof (buf));
1911
      p = buf;
1912
      for (k = 0; k < 4; k++)
1913
        {
1914
          if ((p[k * 2 + 1] == 0) || (p[k * 2 + 2] == 0))
1915
            {
1916
              error ("Emulator reply is too short: %s", buf);
1917
            }
1918
          base_addr[k] = (fromhex (p[k * 2 + 1]) * 16) + fromhex (p[k * 2 + 2]);
1919
        }
1920
      /* base addr of exception vector table */
1921
      memaddress = *((CORE_ADDR *) base_addr);
1922
    }
1923
 
1924
  memaddress += (es1800_break_vec + 32) * 4;    /* address of trap vector */
1925
 
1926
  sprintf (buf, "@.L%lx=$%lx", memaddress, es1800_break_address);
1927
  send_command (buf);           /* set the address of the break routine in the */
1928
  /* trap vector */
1929
 
1930
  sprintf (buf, "@.L%lx=$4E714E71", es1800_break_address);      /* NOP; NOP */
1931
  send_command (buf);
1932
  sprintf (buf, "@.L%lx=$4E714E73", es1800_break_address + 4);  /* NOP; RTE */
1933
  send_command (buf);
1934
 
1935
  sprintf (buf, "AC2=$%lx", es1800_break_address + 4);
1936
  /* breakpoint at es1800-break_address */
1937
  send_command (buf);
1938
  send_command ("WHEN AC2 THEN BRK");   /* ie in exception routine */
1939
 
1940
  if (from_tty)
1941
    {
1942
      printf ("Breakpoint (trap $%x) routine at address: %lx\n",
1943
              es1800_break_vec, es1800_break_address);
1944
    }
1945
}
1946
 
1947
static void
1948
es1800_child_open (char *arg, int from_tty)
1949
{
1950
  error ("Use the \"run\" command to start a child process.");
1951
}
1952
 
1953
static void
1954
es1800_child_detach (char *args, int from_tty)
1955
{
1956
  if (args)
1957
    {
1958
      error ("Argument given to \"detach\" when remotely debugging.");
1959
    }
1960
 
1961
  pop_target ();
1962
  if (from_tty)
1963
    {
1964
      printf ("Ending debugging the process %d.\n", PIDGET (inferior_ptid));
1965
    }
1966
}
1967
 
1968
 
1969
/* Define the target subroutine names  */
1970
 
1971
struct target_ops es1800_ops;
1972
 
1973
static void
1974
init_es1800_ops (void)
1975
{
1976
  es1800_ops.to_shortname = "es1800";
1977
  es1800_ops.to_longname = "Remote serial target in ES1800-emulator protocol";
1978
  es1800_ops.to_doc = "Remote debugging on the es1800 emulator via a serial line.\n\
1979
Specify the serial device it is connected to (e.g. /dev/ttya).";
1980
  es1800_ops.to_open = es1800_open;
1981
  es1800_ops.to_close = es1800_close;
1982
  es1800_ops.to_attach = es1800_attach;
1983
  es1800_ops.to_post_attach = NULL;
1984
  es1800_ops.to_require_attach = NULL;
1985
  es1800_ops.to_detach = es1800_detach;
1986
  es1800_ops.to_require_detach = NULL;
1987
  es1800_ops.to_resume = es1800_resume;
1988
  es1800_ops.to_wait = NULL;
1989
  es1800_ops.to_post_wait = NULL;
1990
  es1800_ops.to_fetch_registers = NULL;
1991
  es1800_ops.to_store_registers = NULL;
1992
  es1800_ops.to_prepare_to_store = es1800_prepare_to_store;
1993
  es1800_ops.to_xfer_memory = es1800_xfer_inferior_memory;
1994
  es1800_ops.to_files_info = es1800_files_info;
1995
  es1800_ops.to_insert_breakpoint = es1800_insert_breakpoint;
1996
  es1800_ops.to_remove_breakpoint = es1800_remove_breakpoint;
1997
  es1800_ops.to_terminal_init = NULL;
1998
  es1800_ops.to_terminal_inferior = NULL;
1999
  es1800_ops.to_terminal_ours_for_output = NULL;
2000
  es1800_ops.to_terminal_ours = NULL;
2001
  es1800_ops.to_terminal_info = NULL;
2002
  es1800_ops.to_kill = NULL;
2003
  es1800_ops.to_load = es1800_load;
2004
  es1800_ops.to_lookup_symbol = NULL;
2005
  es1800_ops.to_create_inferior = es1800_create_inferior;
2006
  es1800_ops.to_post_startup_inferior = NULL;
2007
  es1800_ops.to_acknowledge_created_inferior = NULL;
2008
  es1800_ops.to_clone_and_follow_inferior = NULL;
2009
  es1800_ops.to_post_follow_inferior_by_clone = NULL;
2010
  es1800_ops.to_insert_fork_catchpoint = NULL;
2011
  es1800_ops.to_remove_fork_catchpoint = NULL;
2012
  es1800_ops.to_insert_vfork_catchpoint = NULL;
2013
  es1800_ops.to_remove_vfork_catchpoint = NULL;
2014
  es1800_ops.to_has_forked = NULL;
2015
  es1800_ops.to_has_vforked = NULL;
2016
  es1800_ops.to_can_follow_vfork_prior_to_exec = NULL;
2017
  es1800_ops.to_post_follow_vfork = NULL;
2018
  es1800_ops.to_insert_exec_catchpoint = NULL;
2019
  es1800_ops.to_remove_exec_catchpoint = NULL;
2020
  es1800_ops.to_has_execd = NULL;
2021
  es1800_ops.to_reported_exec_events_per_exec_call = NULL;
2022
  es1800_ops.to_has_exited = NULL;
2023
  es1800_ops.to_mourn_inferior = NULL;
2024
  es1800_ops.to_can_run = 0;
2025
  es1800_ops.to_notice_signals = 0;
2026
  es1800_ops.to_thread_alive = 0;
2027
  es1800_ops.to_stop = 0;
2028
  es1800_ops.to_pid_to_exec_file = NULL;
2029
  es1800_ops.to_stratum = core_stratum;
2030
  es1800_ops.DONT_USE = 0;
2031
  es1800_ops.to_has_all_memory = 0;
2032
  es1800_ops.to_has_memory = 1;
2033
  es1800_ops.to_has_stack = 0;
2034
  es1800_ops.to_has_registers = 0;
2035
  es1800_ops.to_has_execution = 0;
2036
  es1800_ops.to_sections = NULL;
2037
  es1800_ops.to_sections_end = NULL;
2038
  es1800_ops.to_magic = OPS_MAGIC;
2039
}
2040
 
2041
/* Define the target subroutine names  */
2042
 
2043
struct target_ops es1800_child_ops;
2044
 
2045
static void
2046
init_es1800_child_ops (void)
2047
{
2048
  es1800_child_ops.to_shortname = "es1800_process";
2049
  es1800_child_ops.to_longname = "Remote serial target in ES1800-emulator protocol";
2050
  es1800_child_ops.to_doc = "Remote debugging on the es1800 emulator via a serial line.\n\
2051
Specify the serial device it is connected to (e.g. /dev/ttya).";
2052
  es1800_child_ops.to_open = es1800_child_open;
2053
  es1800_child_ops.to_close = NULL;
2054
  es1800_child_ops.to_attach = es1800_attach;
2055
  es1800_child_ops.to_post_attach = NULL;
2056
  es1800_child_ops.to_require_attach = NULL;
2057
  es1800_child_ops.to_detach = es1800_child_detach;
2058
  es1800_child_ops.to_require_detach = NULL;
2059
  es1800_child_ops.to_resume = es1800_resume;
2060
  es1800_child_ops.to_wait = es1800_wait;
2061
  es1800_child_ops.to_post_wait = NULL;
2062
  es1800_child_ops.to_fetch_registers = es1800_fetch_register;
2063
  es1800_child_ops.to_store_registers = es1800_store_register;
2064
  es1800_child_ops.to_prepare_to_store = es1800_prepare_to_store;
2065
  es1800_child_ops.to_xfer_memory = es1800_xfer_inferior_memory;
2066
  es1800_child_ops.to_files_info = es1800_files_info;
2067
  es1800_child_ops.to_insert_breakpoint = es1800_insert_breakpoint;
2068
  es1800_child_ops.to_remove_breakpoint = es1800_remove_breakpoint;
2069
  es1800_child_ops.to_terminal_init = NULL;
2070
  es1800_child_ops.to_terminal_inferior = NULL;
2071
  es1800_child_ops.to_terminal_ours_for_output = NULL;
2072
  es1800_child_ops.to_terminal_ours = NULL;
2073
  es1800_child_ops.to_terminal_info = NULL;
2074
  es1800_child_ops.to_kill = es1800_kill;
2075
  es1800_child_ops.to_load = es1800_load;
2076
  es1800_child_ops.to_lookup_symbol = NULL;
2077
  es1800_child_ops.to_create_inferior = es1800_create_inferior;
2078
  es1800_child_ops.to_post_startup_inferior = NULL;
2079
  es1800_child_ops.to_acknowledge_created_inferior = NULL;
2080
  es1800_child_ops.to_clone_and_follow_inferior = NULL;
2081
  es1800_child_ops.to_post_follow_inferior_by_clone = NULL;
2082
  es1800_child_ops.to_insert_fork_catchpoint = NULL;
2083
  es1800_child_ops.to_remove_fork_catchpoint = NULL;
2084
  es1800_child_ops.to_insert_vfork_catchpoint = NULL;
2085
  es1800_child_ops.to_remove_vfork_catchpoint = NULL;
2086
  es1800_child_ops.to_has_forked = NULL;
2087
  es1800_child_ops.to_has_vforked = NULL;
2088
  es1800_child_ops.to_can_follow_vfork_prior_to_exec = NULL;
2089
  es1800_child_ops.to_post_follow_vfork = NULL;
2090
  es1800_child_ops.to_insert_exec_catchpoint = NULL;
2091
  es1800_child_ops.to_remove_exec_catchpoint = NULL;
2092
  es1800_child_ops.to_has_execd = NULL;
2093
  es1800_child_ops.to_reported_exec_events_per_exec_call = NULL;
2094
  es1800_child_ops.to_has_exited = NULL;
2095
  es1800_child_ops.to_mourn_inferior = es1800_mourn_inferior;
2096
  es1800_child_ops.to_can_run = 0;
2097
  es1800_child_ops.to_notice_signals = 0;
2098
  es1800_child_ops.to_thread_alive = 0;
2099
  es1800_child_ops.to_stop = 0;
2100
  es1800_child_ops.to_pid_to_exec_file = NULL;
2101
  es1800_child_ops.to_stratum = process_stratum;
2102
  es1800_child_ops.DONT_USE = 0;
2103
  es1800_child_ops.to_has_all_memory = 1;
2104
  es1800_child_ops.to_has_memory = 1;
2105
  es1800_child_ops.to_has_stack = 1;
2106
  es1800_child_ops.to_has_registers = 1;
2107
  es1800_child_ops.to_has_execution = 1;
2108
  es1800_child_ops.to_sections = NULL;
2109
  es1800_child_ops.to_sections_end = NULL;
2110
  es1800_child_ops.to_magic = OPS_MAGIC;
2111
}
2112
 
2113
void
2114
_initialize_es1800 (void)
2115
{
2116
  init_es1800_ops ();
2117
  init_es1800_child_ops ();
2118
  add_target (&es1800_ops);
2119
  add_target (&es1800_child_ops);
2120
#ifdef PROVIDE_TRANSPARENT
2121
  add_com ("transparent", class_support, es1800_transparent,
2122
           "Start transparent communication with the ES 1800 emulator.");
2123
#endif /* PROVIDE_TRANSPARENT */
2124
  add_com ("init_break", class_support, es1800_init_break,
2125
         "Download break routine and initialize break facility on ES 1800");
2126
}

powered by: WebSVN 2.1.0

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