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

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [gdb/] [ocd.c] - Blame information for rev 1778

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

Line No. Rev Author Line
1 1181 sfurman
/* Target communications support for Macraigor Systems' On-Chip Debugging
2
 
3
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
4
   Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
#include "defs.h"
24
#include "gdbcore.h"
25
#include "gdb_string.h"
26
#include <fcntl.h>
27
#include "frame.h"
28
#include "inferior.h"
29
#include "bfd.h"
30
#include "symfile.h"
31
#include "target.h"
32
#include "gdbcmd.h"
33
#include "objfiles.h"
34
#include "gdb-stabs.h"
35
#include <sys/types.h>
36
#include <signal.h>
37
#include "serial.h"
38
#include "ocd.h"
39
#include "regcache.h"
40
 
41
/* Prototypes for local functions */
42
 
43
static int ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len);
44
 
45
static int ocd_start_remote (PTR dummy);
46
 
47
static int readchar (int timeout);
48
 
49
static void reset_packet (void);
50
 
51
static void output_packet (void);
52
 
53
static int get_quoted_char (int timeout);
54
 
55
static void put_quoted_char (int c);
56
 
57
static void ocd_interrupt (int signo);
58
 
59
static void ocd_interrupt_twice (int signo);
60
 
61
static void interrupt_query (void);
62
 
63
static unsigned char *ocd_do_command (int cmd, int *statusp, int *lenp);
64
 
65
static void ocd_put_packet (unsigned char *packet, int pktlen);
66
 
67
static unsigned char *ocd_get_packet (int cmd, int *pktlen, int timeout);
68
 
69
static struct target_ops *current_ops = NULL;
70
 
71
static int last_run_status;
72
 
73
/* This was 5 seconds, which is a long time to sit and wait.
74
   Unless this is going though some terminal server or multiplexer or
75
   other form of hairy serial connection, I would think 2 seconds would
76
   be plenty.  */
77
 
78
#if 0
79
/* FIXME: Change to allow option to set timeout value on a per target
80
   basis. */
81
static int remote_timeout = 2;
82
#endif
83
 
84
/* Descriptor for I/O to remote machine.  Initialize it to NULL so that
85
   ocd_open knows that we don't have a file open when the program
86
   starts.  */
87
static struct serial *ocd_desc = NULL;
88
 
89
void
90
ocd_error (char *s, int error_code)
91
{
92
  char buf[100];
93
 
94
  fputs_filtered (s, gdb_stderr);
95
  fputs_filtered (" ", gdb_stderr);
96
 
97
  switch (error_code)
98
    {
99
    case 0x1:
100
      s = "Unknown fault";
101
      break;
102
    case 0x2:
103
      s = "Power failed";
104
      break;
105
    case 0x3:
106
      s = "Cable disconnected";
107
      break;
108
    case 0x4:
109
      s = "Couldn't enter OCD mode";
110
      break;
111
    case 0x5:
112
      s = "Target stuck in reset";
113
      break;
114
    case 0x6:
115
      s = "OCD hasn't been initialized";
116
      break;
117
    case 0x7:
118
      s = "Write verify failed";
119
      break;
120
    case 0x8:
121
      s = "Reg buff error (during MPC5xx fp reg read/write)";
122
      break;
123
    case 0x9:
124
      s = "Invalid CPU register access attempt failed";
125
      break;
126
    case 0x11:
127
      s = "Bus error";
128
      break;
129
    case 0x12:
130
      s = "Checksum error";
131
      break;
132
    case 0x13:
133
      s = "Illegal command";
134
      break;
135
    case 0x14:
136
      s = "Parameter error";
137
      break;
138
    case 0x15:
139
      s = "Internal error";
140
      break;
141
    case 0x80:
142
      s = "Flash erase error";
143
      break;
144
    default:
145
      sprintf (buf, "Unknown error code %d", error_code);
146
      s = buf;
147
    }
148
 
149
  error (s);
150
}
151
 
152
/*  Return nonzero if the thread TH is still alive on the remote system.  */
153
 
154
int
155
ocd_thread_alive (ptid_t th)
156
{
157
  return 1;
158
}
159
 
160
/* Clean up connection to a remote debugger.  */
161
 
162
/* ARGSUSED */
163
void
164
ocd_close (int quitting)
165
{
166
  if (ocd_desc)
167
    serial_close (ocd_desc);
168
  ocd_desc = NULL;
169
}
170
 
171
/* Stub for catch_errors.  */
172
 
173
static int
174
ocd_start_remote (PTR dummy)
175
{
176
  unsigned char buf[10], *p;
177
  int pktlen;
178
  int status;
179
  int error_code;
180
  int speed;
181
  enum ocd_target_type target_type;
182
 
183
  target_type = *(enum ocd_target_type *) dummy;
184
 
185
  immediate_quit++;             /* Allow user to interrupt it */
186
 
187
  serial_send_break (ocd_desc); /* Wake up the wiggler */
188
 
189
  speed = 80;                   /* Divide clock by 4000 */
190
 
191
  buf[0] = OCD_INIT;
192
  buf[1] = speed >> 8;
193
  buf[2] = speed & 0xff;
194
  buf[3] = target_type;
195
  ocd_put_packet (buf, 4);      /* Init OCD params */
196
  p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
197
 
198
  if (pktlen < 2)
199
    error ("Truncated response packet from OCD device");
200
 
201
  status = p[1];
202
  error_code = p[2];
203
 
204
  if (error_code != 0)
205
    ocd_error ("OCD_INIT:", error_code);
206
 
207
  ocd_do_command (OCD_AYT, &status, &pktlen);
208
 
209
  p = ocd_do_command (OCD_GET_VERSION, &status, &pktlen);
210
 
211
  printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
212
                     p[0], p[1], (p[2] << 16) | p[3]);
213
 
214
#if 0
215
  /* Reset the target */
216
 
217
  ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
218
/*  ocd_do_command (OCD_RESET, &status, &pktlen); */
219
#endif
220
 
221
  /* If processor is still running, stop it.  */
222
 
223
  if (!(status & OCD_FLAG_BDM))
224
    ocd_stop ();
225
 
226
#if 1
227
  /* When using a target box, we want to asynchronously return status when
228
     target stops.  The OCD_SET_CTL_FLAGS command is ignored by Wigglers.dll
229
     when using a parallel Wiggler */
230
  buf[0] = OCD_SET_CTL_FLAGS;
231
  buf[1] = 0;
232
  buf[2] = 1;
233
  ocd_put_packet (buf, 3);
234
 
235
  p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
236
 
237
  if (pktlen < 2)
238
    error ("Truncated response packet from OCD device");
239
 
240
  status = p[1];
241
  error_code = p[2];
242
 
243
  if (error_code != 0)
244
    ocd_error ("OCD_SET_CTL_FLAGS:", error_code);
245
#endif
246
 
247
  immediate_quit--;
248
 
249
/* This is really the job of start_remote however, that makes an assumption
250
   that the target is about to print out a status message of some sort.  That
251
   doesn't happen here (in fact, it may not be possible to get the monitor to
252
   send the appropriate packet).  */
253
 
254
  flush_cached_frames ();
255
  registers_changed ();
256
  stop_pc = read_pc ();
257
  set_current_frame (create_new_frame (read_fp (), stop_pc));
258
  select_frame (get_current_frame ());
259
  print_stack_frame (selected_frame, -1, 1);
260
 
261
  buf[0] = OCD_LOG_FILE;
262
  buf[1] = 3;                   /* close existing WIGGLERS.LOG */
263
  ocd_put_packet (buf, 2);
264
  p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
265
 
266
  buf[0] = OCD_LOG_FILE;
267
  buf[1] = 2;                   /* append to existing WIGGLERS.LOG */
268
  ocd_put_packet (buf, 2);
269
  p = ocd_get_packet (buf[0], &pktlen, remote_timeout);
270
 
271
  return 1;
272
}
273
 
274
/* Open a connection to a remote debugger.
275
   NAME is the filename used for communication.  */
276
 
277
void
278
ocd_open (char *name, int from_tty, enum ocd_target_type target_type,
279
          struct target_ops *ops)
280
{
281
  unsigned char buf[10], *p;
282
  int pktlen;
283
 
284
  if (name == 0)
285
    error ("To open an OCD connection, you need to specify the\n\
286
device the OCD device is attached to (e.g. /dev/ttya).");
287
 
288
  target_preopen (from_tty);
289
 
290
  current_ops = ops;
291
 
292
  unpush_target (current_ops);
293
 
294
  ocd_desc = serial_open (name);
295
  if (!ocd_desc)
296
    perror_with_name (name);
297
 
298
  if (baud_rate != -1)
299
    {
300
      if (serial_setbaudrate (ocd_desc, baud_rate))
301
        {
302
          serial_close (ocd_desc);
303
          perror_with_name (name);
304
        }
305
    }
306
 
307
  serial_raw (ocd_desc);
308
 
309
  /* If there is something sitting in the buffer we might take it as a
310
     response to a command, which would be bad.  */
311
  serial_flush_input (ocd_desc);
312
 
313
  if (from_tty)
314
    {
315
      puts_filtered ("Remote target wiggler connected to ");
316
      puts_filtered (name);
317
      puts_filtered ("\n");
318
    }
319
  push_target (current_ops);    /* Switch to using remote target now */
320
 
321
  /* Without this, some commands which require an active target (such as kill)
322
     won't work.  This variable serves (at least) double duty as both the pid
323
     of the target process (if it has such), and as a flag indicating that a
324
     target is active.  These functions should be split out into seperate
325
     variables, especially since GDB will someday have a notion of debugging
326
     several processes.  */
327
 
328
  inferior_ptid = pid_to_ptid (42000);
329
  /* Start the remote connection; if error (0), discard this target.
330
     In particular, if the user quits, be sure to discard it
331
     (we'd be in an inconsistent state otherwise).  */
332
  if (!catch_errors (ocd_start_remote, &target_type,
333
                     "Couldn't establish connection to remote target\n",
334
                     RETURN_MASK_ALL))
335
    {
336
      pop_target ();
337
      error ("Failed to connect to OCD.");
338
    }
339
}
340
 
341
/* This takes a program previously attached to and detaches it.  After
342
   this is done, GDB can be used to debug some other program.  We
343
   better not have left any breakpoints in the target program or it'll
344
   die when it hits one.  */
345
 
346
void
347
ocd_detach (char *args, int from_tty)
348
{
349
  if (args)
350
    error ("Argument given to \"detach\" when remotely debugging.");
351
 
352
  pop_target ();
353
  if (from_tty)
354
    puts_filtered ("Ending remote debugging.\n");
355
}
356
 
357
/* Tell the remote machine to resume.  */
358
 
359
void
360
ocd_resume (ptid_t ptid, int step, enum target_signal siggnal)
361
{
362
  int pktlen;
363
 
364
  if (step)
365
    ocd_do_command (OCD_STEP, &last_run_status, &pktlen);
366
  else
367
    ocd_do_command (OCD_RUN, &last_run_status, &pktlen);
368
}
369
 
370
void
371
ocd_stop (void)
372
{
373
  int status;
374
  int pktlen;
375
 
376
  ocd_do_command (OCD_STOP, &status, &pktlen);
377
 
378
  if (!(status & OCD_FLAG_BDM))
379
    error ("Can't stop target via BDM");
380
}
381
 
382
static volatile int ocd_interrupt_flag;
383
 
384
/* Send ^C to target to halt it.  Target will respond, and send us a
385
   packet.  */
386
 
387
static void
388
ocd_interrupt (int signo)
389
{
390
  /* If this doesn't work, try more severe steps.  */
391
  signal (signo, ocd_interrupt_twice);
392
 
393
  if (remote_debug)
394
    printf_unfiltered ("ocd_interrupt called\n");
395
 
396
  {
397
    char buf[1];
398
 
399
    ocd_stop ();
400
    buf[0] = OCD_AYT;
401
    ocd_put_packet (buf, 1);
402
    ocd_interrupt_flag = 1;
403
  }
404
}
405
 
406
static void (*ofunc) ();
407
 
408
/* The user typed ^C twice.  */
409
static void
410
ocd_interrupt_twice (int signo)
411
{
412
  signal (signo, ofunc);
413
 
414
  interrupt_query ();
415
 
416
  signal (signo, ocd_interrupt);
417
}
418
 
419
/* Ask the user what to do when an interrupt is received.  */
420
 
421
static void
422
interrupt_query (void)
423
{
424
  target_terminal_ours ();
425
 
426
  if (query ("Interrupted while waiting for the program.\n\
427
Give up (and stop debugging it)? "))
428
    {
429
      target_mourn_inferior ();
430
      throw_exception (RETURN_QUIT);
431
    }
432
 
433
  target_terminal_inferior ();
434
}
435
 
436
/* If nonzero, ignore the next kill.  */
437
static int kill_kludge;
438
 
439
/* Wait until the remote machine stops, then return,
440
   storing status in STATUS just as `wait' would.
441
   Returns "pid" (though it's not clear what, if anything, that
442
   means in the case of this target).  */
443
 
444
int
445
ocd_wait (void)
446
{
447
  unsigned char *p;
448
  int error_code;
449
  int pktlen;
450
  char buf[1];
451
 
452
  ocd_interrupt_flag = 0;
453
 
454
  /* Target might already be stopped by the time we get here. */
455
  /* If we aren't already stopped, we need to loop until we've dropped
456
     back into BDM mode */
457
 
458
  while (!(last_run_status & OCD_FLAG_BDM))
459
    {
460
      buf[0] = OCD_AYT;
461
      ocd_put_packet (buf, 1);
462
      p = ocd_get_packet (OCD_AYT, &pktlen, -1);
463
 
464
      ofunc = (void (*)()) signal (SIGINT, ocd_interrupt);
465
      signal (SIGINT, ofunc);
466
 
467
      if (pktlen < 2)
468
        error ("Truncated response packet from OCD device");
469
 
470
      last_run_status = p[1];
471
      error_code = p[2];
472
 
473
      if (error_code != 0)
474
        ocd_error ("target_wait:", error_code);
475
 
476
      if (last_run_status & OCD_FLAG_PWF)
477
        error ("OCD device lost VCC at BDM interface.");
478
      else if (last_run_status & OCD_FLAG_CABLE_DISC)
479
        error ("OCD device cable appears to have been disconnected.");
480
    }
481
 
482
  if (ocd_interrupt_flag)
483
    return 1;
484
  else
485
    return 0;
486
}
487
 
488
/* Read registers from the OCD device.  Specify the starting and ending
489
   register number.  Return the number of regs actually read in *NUMREGS.
490
   Returns a pointer to a static array containing the register contents.  */
491
 
492
unsigned char *
493
ocd_read_bdm_registers (int first_bdm_regno, int last_bdm_regno, int *reglen)
494
{
495
  unsigned char buf[10];
496
  int i;
497
  unsigned char *p;
498
  unsigned char *regs;
499
  int error_code, status;
500
  int pktlen;
501
 
502
  buf[0] = OCD_READ_REGS;
503
  buf[1] = first_bdm_regno >> 8;
504
  buf[2] = first_bdm_regno & 0xff;
505
  buf[3] = last_bdm_regno >> 8;
506
  buf[4] = last_bdm_regno & 0xff;
507
 
508
  ocd_put_packet (buf, 5);
509
  p = ocd_get_packet (OCD_READ_REGS, &pktlen, remote_timeout);
510
 
511
  status = p[1];
512
  error_code = p[2];
513
 
514
  if (error_code != 0)
515
    ocd_error ("read_bdm_registers:", error_code);
516
 
517
  i = p[3];
518
  if (i == 0)
519
    i = 256;
520
 
521
  if (i > pktlen - 4
522
      || ((i & 3) != 0))
523
    error ("Register block size bad:  %d", i);
524
 
525
  *reglen = i;
526
 
527
  regs = p + 4;
528
 
529
  return regs;
530
}
531
 
532
/* Read register BDM_REGNO and returns its value ala read_register() */
533
 
534
CORE_ADDR
535
ocd_read_bdm_register (int bdm_regno)
536
{
537
  int reglen;
538
  unsigned char *p;
539
  CORE_ADDR regval;
540
 
541
  p = ocd_read_bdm_registers (bdm_regno, bdm_regno, &reglen);
542
  regval = extract_unsigned_integer (p, reglen);
543
 
544
  return regval;
545
}
546
 
547
void
548
ocd_write_bdm_registers (int first_bdm_regno, unsigned char *regptr, int reglen)
549
{
550
  unsigned char *buf;
551
  unsigned char *p;
552
  int error_code, status;
553
  int pktlen;
554
 
555
  buf = alloca (4 + reglen);
556
 
557
  buf[0] = OCD_WRITE_REGS;
558
  buf[1] = first_bdm_regno >> 8;
559
  buf[2] = first_bdm_regno & 0xff;
560
  buf[3] = reglen;
561
  memcpy (buf + 4, regptr, reglen);
562
 
563
  ocd_put_packet (buf, 4 + reglen);
564
  p = ocd_get_packet (OCD_WRITE_REGS, &pktlen, remote_timeout);
565
 
566
  if (pktlen < 3)
567
    error ("Truncated response packet from OCD device");
568
 
569
  status = p[1];
570
  error_code = p[2];
571
 
572
  if (error_code != 0)
573
    ocd_error ("ocd_write_bdm_registers:", error_code);
574
}
575
 
576
void
577
ocd_write_bdm_register (int bdm_regno, CORE_ADDR reg)
578
{
579
  unsigned char buf[4];
580
 
581
  store_unsigned_integer (buf, 4, reg);
582
 
583
  ocd_write_bdm_registers (bdm_regno, buf, 4);
584
}
585
 
586
void
587
ocd_prepare_to_store (void)
588
{
589
}
590
 
591
/* Write memory data directly to the remote machine.
592
   This does not inform the data cache; the data cache uses this.
593
   MEMADDR is the address in the remote memory space.
594
   MYADDR is the address of the buffer in our space.
595
   LEN is the number of bytes.
596
 
597
   Returns number of bytes transferred, or 0 for error.  */
598
 
599
static int write_mem_command = OCD_WRITE_MEM;
600
 
601
int
602
ocd_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
603
{
604
  char buf[256 + 10];
605
  unsigned char *p;
606
  int origlen;
607
 
608
  origlen = len;
609
 
610
  buf[0] = write_mem_command;
611
  buf[5] = 1;                   /* Write as bytes */
612
  buf[6] = 0;                    /* Don't verify */
613
 
614
  while (len > 0)
615
    {
616
      int numbytes;
617
      int pktlen;
618
      int status, error_code;
619
 
620
      numbytes = min (len, 256 - 8);
621
 
622
      buf[1] = memaddr >> 24;
623
      buf[2] = memaddr >> 16;
624
      buf[3] = memaddr >> 8;
625
      buf[4] = memaddr;
626
 
627
      buf[7] = numbytes;
628
 
629
      memcpy (&buf[8], myaddr, numbytes);
630
      ocd_put_packet (buf, 8 + numbytes);
631
      p = ocd_get_packet (OCD_WRITE_MEM, &pktlen, remote_timeout);
632
      if (pktlen < 3)
633
        error ("Truncated response packet from OCD device");
634
 
635
      status = p[1];
636
      error_code = p[2];
637
 
638
      if (error_code == 0x11)   /* Got a bus error? */
639
        {
640
          CORE_ADDR error_address;
641
 
642
          error_address = p[3] << 24;
643
          error_address |= p[4] << 16;
644
          error_address |= p[5] << 8;
645
          error_address |= p[6];
646
          numbytes = error_address - memaddr;
647
 
648
          len -= numbytes;
649
 
650
          errno = EIO;
651
 
652
          break;
653
        }
654
      else if (error_code != 0)
655
        ocd_error ("ocd_write_bytes:", error_code);
656
 
657
      len -= numbytes;
658
      memaddr += numbytes;
659
      myaddr += numbytes;
660
    }
661
 
662
  return origlen - len;
663
}
664
 
665
/* Read memory data directly from the remote machine.
666
   This does not use the data cache; the data cache uses this.
667
   MEMADDR is the address in the remote memory space.
668
   MYADDR is the address of the buffer in our space.
669
   LEN is the number of bytes.
670
 
671
   Returns number of bytes transferred, or 0 for error.  */
672
 
673
static int
674
ocd_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
675
{
676
  char buf[256 + 10];
677
  unsigned char *p;
678
  int origlen;
679
 
680
  origlen = len;
681
 
682
  buf[0] = OCD_READ_MEM;
683
  buf[5] = 1;                   /* Read as bytes */
684
 
685
  while (len > 0)
686
    {
687
      int numbytes;
688
      int pktlen;
689
      int status, error_code;
690
 
691
      numbytes = min (len, 256 - 7);
692
 
693
      buf[1] = memaddr >> 24;
694
      buf[2] = memaddr >> 16;
695
      buf[3] = memaddr >> 8;
696
      buf[4] = memaddr;
697
 
698
      buf[6] = numbytes;
699
 
700
      ocd_put_packet (buf, 7);
701
      p = ocd_get_packet (OCD_READ_MEM, &pktlen, remote_timeout);
702
      if (pktlen < 4)
703
        error ("Truncated response packet from OCD device");
704
 
705
      status = p[1];
706
      error_code = p[2];
707
 
708
      if (error_code == 0x11)   /* Got a bus error? */
709
        {
710
          CORE_ADDR error_address;
711
 
712
          error_address = p[3] << 24;
713
          error_address |= p[4] << 16;
714
          error_address |= p[5] << 8;
715
          error_address |= p[6];
716
          numbytes = error_address - memaddr;
717
 
718
          len -= numbytes;
719
 
720
          errno = EIO;
721
 
722
          break;
723
        }
724
      else if (error_code != 0)
725
        ocd_error ("ocd_read_bytes:", error_code);
726
 
727
      memcpy (myaddr, &p[4], numbytes);
728
 
729
      len -= numbytes;
730
      memaddr += numbytes;
731
      myaddr += numbytes;
732
    }
733
 
734
  return origlen - len;
735
}
736
 
737
/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
738
   to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
739
   nonzero.  Returns length of data written or read; 0 for error.  TARGET
740
   is ignored.  */
741
 
742
/* ARGSUSED */
743
int
744
ocd_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
745
                 struct mem_attrib *attrib, struct target_ops *target)
746
{
747
  int res;
748
 
749
  if (should_write)
750
    res = ocd_write_bytes (memaddr, myaddr, len);
751
  else
752
    res = ocd_read_bytes (memaddr, myaddr, len);
753
 
754
  return res;
755
}
756
 
757
void
758
ocd_files_info (struct target_ops *ignore)
759
{
760
  puts_filtered ("Debugging a target over a serial line.\n");
761
}
762
 
763
/* Stuff for dealing with the packets which are part of this protocol.
764
   See comment at top of file for details.  */
765
 
766
/* Read a single character from the remote side, handling wierd errors. */
767
 
768
static int
769
readchar (int timeout)
770
{
771
  int ch;
772
 
773
  ch = serial_readchar (ocd_desc, timeout);
774
 
775
  switch (ch)
776
    {
777
    case SERIAL_EOF:
778
      error ("Remote connection closed");
779
    case SERIAL_ERROR:
780
      perror_with_name ("Remote communication error");
781
    case SERIAL_TIMEOUT:
782
    default:
783
      return ch;
784
    }
785
}
786
 
787
#if 0
788
/* Read a character from the data stream, dequoting as necessary.  SYN is
789
   treated special.  Any SYNs appearing in the data stream are returned as the
790
   distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
791
   mistaken for real data).  */
792
 
793
static int
794
get_quoted_char (int timeout)
795
{
796
  int ch;
797
 
798
  ch = readchar (timeout);
799
 
800
  switch (ch)
801
    {
802
    case SERIAL_TIMEOUT:
803
      error ("Timeout in mid-packet, aborting");
804
    case SYN:
805
      return RAW_SYN;
806
    case DLE:
807
      ch = readchar (timeout);
808
      if (ch == SYN)
809
        return RAW_SYN;
810
      return ch & ~0100;
811
    default:
812
      return ch;
813
    }
814
}
815
 
816
static unsigned char pkt[256 * 2 + 10], *pktp;  /* Worst case */
817
 
818
static void
819
reset_packet (void)
820
{
821
  pktp = pkt;
822
}
823
 
824
static void
825
output_packet (void)
826
{
827
  if (serial_write (ocd_desc, pkt, pktp - pkt))
828
    perror_with_name ("output_packet: write failed");
829
 
830
  reset_packet ();
831
}
832
 
833
/* Output a quoted character.  SYNs and DLEs are quoted.  Everything else goes
834
   through untouched.  */
835
 
836
static void
837
put_quoted_char (int c)
838
{
839
  switch (c)
840
    {
841
    case SYN:
842
    case DLE:
843
      *pktp++ = DLE;
844
      c |= 0100;
845
    }
846
 
847
  *pktp++ = c;
848
}
849
 
850
/* Send a packet to the OCD device.  The packet framed by a SYN character,
851
   a byte count and a checksum.  The byte count only counts the number of
852
   bytes between the count and the checksum.  A count of zero actually
853
   means 256.  Any SYNs within the packet (including the checksum and
854
   count) must be quoted.  The quote character must be quoted as well.
855
   Quoting is done by replacing the character with the two-character sequence
856
   DLE, {char} | 0100.  Note that the quoting mechanism has no effect on the
857
   byte count. */
858
 
859
static void
860
stu_put_packet (unsigned char *buf, int len)
861
{
862
  unsigned char checksum;
863
  unsigned char c;
864
 
865
  if (len == 0 || len > 256)
866
    internal_error (__FILE__, __LINE__, "failed internal consistency check");                   /* Can't represent 0 length packet */
867
 
868
  reset_packet ();
869
 
870
  checksum = 0;
871
 
872
  put_quoted_char (RAW_SYN);
873
 
874
  c = len;
875
 
876
  do
877
    {
878
      checksum += c;
879
 
880
      put_quoted_char (c);
881
 
882
      c = *buf++;
883
    }
884
  while (len-- > 0);
885
 
886
  put_quoted_char (-checksum & 0xff);
887
 
888
  output_packet ();
889
}
890
 
891
#else
892
 
893
/* Send a packet to the OCD device.  The packet framed by a SYN character,
894
   a byte count and a checksum.  The byte count only counts the number of
895
   bytes between the count and the checksum.  A count of zero actually
896
   means 256.  Any SYNs within the packet (including the checksum and
897
   count) must be quoted.  The quote character must be quoted as well.
898
   Quoting is done by replacing the character with the two-character sequence
899
   DLE, {char} | 0100.  Note that the quoting mechanism has no effect on the
900
   byte count.  */
901
 
902
static void
903
ocd_put_packet (unsigned char *buf, int len)
904
{
905
  unsigned char checksum;
906
  unsigned char c;
907
  unsigned char *packet, *packet_ptr;
908
 
909
  packet = alloca (len + 1 + 1);        /* packet + SYN + checksum */
910
  packet_ptr = packet;
911
 
912
  checksum = 0;
913
 
914
  *packet_ptr++ = 0x55;
915
 
916
  while (len-- > 0)
917
    {
918
      c = *buf++;
919
 
920
      checksum += c;
921
      *packet_ptr++ = c;
922
    }
923
 
924
  *packet_ptr++ = -checksum;
925
  if (serial_write (ocd_desc, packet, packet_ptr - packet))
926
    perror_with_name ("output_packet: write failed");
927
}
928
#endif
929
 
930
#if 0
931
/* Get a packet from the OCD device.  Timeout is only enforced for the
932
   first byte of the packet.  Subsequent bytes are expected to arrive in
933
   time <= remote_timeout.  Returns a pointer to a static buffer containing
934
   the payload of the packet.  *LENP contains the length of the packet.
935
 */
936
 
937
static unsigned char *
938
stu_get_packet (unsigned char cmd, int *lenp, int timeout)
939
{
940
  int ch;
941
  int len;
942
  static unsigned char buf[256 + 10], *p;
943
  unsigned char checksum;
944
 
945
find_packet:
946
 
947
  ch = get_quoted_char (timeout);
948
 
949
  if (ch < 0)
950
    error ("get_packet (readchar): %d", ch);
951
 
952
  if (ch != RAW_SYN)
953
    goto find_packet;
954
 
955
found_syn:                      /* Found the start of a packet */
956
 
957
  p = buf;
958
  checksum = 0;
959
 
960
  len = get_quoted_char (remote_timeout);
961
 
962
  if (len == RAW_SYN)
963
    goto found_syn;
964
 
965
  checksum += len;
966
 
967
  if (len == 0)
968
    len = 256;
969
 
970
  len++;                        /* Include checksum */
971
 
972
  while (len-- > 0)
973
    {
974
      ch = get_quoted_char (remote_timeout);
975
      if (ch == RAW_SYN)
976
        goto found_syn;
977
 
978
      *p++ = ch;
979
      checksum += ch;
980
    }
981
 
982
  if (checksum != 0)
983
    goto find_packet;
984
 
985
  if (cmd != buf[0])
986
    error ("Response phase error.  Got 0x%x, expected 0x%x", buf[0], cmd);
987
 
988
  *lenp = p - buf - 1;
989
  return buf;
990
}
991
 
992
#else
993
 
994
/* Get a packet from the OCD device.  Timeout is only enforced for the
995
   first byte of the packet.  Subsequent bytes are expected to arrive in
996
   time <= remote_timeout.  Returns a pointer to a static buffer containing
997
   the payload of the packet.  *LENP contains the length of the packet.
998
 */
999
 
1000
static unsigned char *
1001
ocd_get_packet (int cmd, int *lenp, int timeout)
1002
{
1003
  int ch;
1004
  int len;
1005
  static unsigned char packet[512];
1006
  unsigned char *packet_ptr;
1007
  unsigned char checksum;
1008
 
1009
  ch = readchar (timeout);
1010
 
1011
  if (ch < 0)
1012
    error ("ocd_get_packet (readchar): %d", ch);
1013
 
1014
  if (ch != 0x55)
1015
    error ("ocd_get_packet (readchar): %d", ch);
1016
 
1017
/* Found the start of a packet */
1018
 
1019
  packet_ptr = packet;
1020
  checksum = 0;
1021
 
1022
/* Read command char.  That sort of tells us how long the packet is. */
1023
 
1024
  ch = readchar (timeout);
1025
 
1026
  if (ch < 0)
1027
    error ("ocd_get_packet (readchar): %d", ch);
1028
 
1029
  *packet_ptr++ = ch;
1030
  checksum += ch;
1031
 
1032
/* Get status. */
1033
 
1034
  ch = readchar (timeout);
1035
 
1036
  if (ch < 0)
1037
    error ("ocd_get_packet (readchar): %d", ch);
1038
  *packet_ptr++ = ch;
1039
  checksum += ch;
1040
 
1041
/* Get error code. */
1042
 
1043
  ch = readchar (timeout);
1044
 
1045
  if (ch < 0)
1046
    error ("ocd_get_packet (readchar): %d", ch);
1047
  *packet_ptr++ = ch;
1048
  checksum += ch;
1049
 
1050
  switch (ch)                   /* Figure out length of packet */
1051
    {
1052
    case 0x7:                   /* Write verify error? */
1053
      len = 8;                  /* write address, value read back */
1054
      break;
1055
    case 0x11:                  /* Bus error? */
1056
      /* write address, read flag */
1057
    case 0x15:                  /* Internal error */
1058
      len = 5;                  /* error code, vector */
1059
      break;
1060
    default:                    /* Error w/no params */
1061
      len = 0;
1062
      break;
1063
    case 0x0:                   /* Normal result */
1064
      switch (packet[0])
1065
        {
1066
        case OCD_AYT:           /* Are You There? */
1067
        case OCD_SET_BAUD_RATE: /* Set Baud Rate */
1068
        case OCD_INIT:          /* Initialize OCD device */
1069
        case OCD_SET_SPEED:     /* Set Speed */
1070
        case OCD_SET_FUNC_CODE: /* Set Function Code */
1071
        case OCD_SET_CTL_FLAGS: /* Set Control Flags */
1072
        case OCD_SET_BUF_ADDR:  /* Set Register Buffer Address */
1073
        case OCD_RUN:           /* Run Target from PC  */
1074
        case OCD_RUN_ADDR:      /* Run Target from Specified Address  */
1075
        case OCD_STOP:          /* Stop Target */
1076
        case OCD_RESET_RUN:     /* Reset Target and Run */
1077
        case OCD_RESET: /* Reset Target and Halt */
1078
        case OCD_STEP:          /* Single Step */
1079
        case OCD_WRITE_REGS:    /* Write Register */
1080
        case OCD_WRITE_MEM:     /* Write Memory */
1081
        case OCD_FILL_MEM:      /* Fill Memory */
1082
        case OCD_MOVE_MEM:      /* Move Memory */
1083
        case OCD_WRITE_INT_MEM: /* Write Internal Memory */
1084
        case OCD_JUMP:          /* Jump to Subroutine */
1085
        case OCD_ERASE_FLASH:   /* Erase flash memory */
1086
        case OCD_PROGRAM_FLASH: /* Write flash memory */
1087
        case OCD_EXIT_MON:      /* Exit the flash programming monitor  */
1088
        case OCD_ENTER_MON:     /* Enter the flash programming monitor  */
1089
        case OCD_LOG_FILE:      /* Make Wigglers.dll save Wigglers.log */
1090
        case OCD_SET_CONNECTION:        /* Set type of connection in Wigglers.dll */
1091
          len = 0;
1092
          break;
1093
        case OCD_GET_VERSION:   /* Get Version */
1094
          len = 10;
1095
          break;
1096
        case OCD_GET_STATUS_MASK:       /* Get Status Mask */
1097
          len = 1;
1098
          break;
1099
        case OCD_GET_CTRS:      /* Get Error Counters */
1100
        case OCD_READ_REGS:     /* Read Register */
1101
        case OCD_READ_MEM:      /* Read Memory */
1102
        case OCD_READ_INT_MEM:  /* Read Internal Memory */
1103
          len = 257;
1104
          break;
1105
        default:
1106
          error ("ocd_get_packet: unknown packet type 0x%x\n", ch);
1107
        }
1108
    }
1109
 
1110
  if (len == 257)               /* Byte stream? */
1111
    {                           /* Yes, byte streams contain the length */
1112
      ch = readchar (timeout);
1113
 
1114
      if (ch < 0)
1115
        error ("ocd_get_packet (readchar): %d", ch);
1116
      *packet_ptr++ = ch;
1117
      checksum += ch;
1118
      len = ch;
1119
      if (len == 0)
1120
        len = 256;
1121
    }
1122
 
1123
  while (len-- >= 0)             /* Do rest of packet and checksum */
1124
    {
1125
      ch = readchar (timeout);
1126
 
1127
      if (ch < 0)
1128
        error ("ocd_get_packet (readchar): %d", ch);
1129
      *packet_ptr++ = ch;
1130
      checksum += ch;
1131
    }
1132
 
1133
  if (checksum != 0)
1134
    error ("ocd_get_packet: bad packet checksum");
1135
 
1136
  if (cmd != -1 && cmd != packet[0])
1137
    error ("Response phase error.  Got 0x%x, expected 0x%x", packet[0], cmd);
1138
 
1139
  *lenp = packet_ptr - packet - 1;      /* Subtract checksum byte */
1140
  return packet;
1141
}
1142
#endif
1143
 
1144
/* Execute a simple (one-byte) command.  Returns a pointer to the data
1145
   following the error code.  */
1146
 
1147
static unsigned char *
1148
ocd_do_command (int cmd, int *statusp, int *lenp)
1149
{
1150
  unsigned char buf[100], *p;
1151
  int status, error_code;
1152
  char errbuf[100];
1153
 
1154
  unsigned char logbuf[100];
1155
  int logpktlen;
1156
 
1157
  buf[0] = cmd;
1158
  ocd_put_packet (buf, 1);      /* Send command */
1159
  p = ocd_get_packet (*buf, lenp, remote_timeout);
1160
 
1161
  if (*lenp < 3)
1162
    error ("Truncated response packet from OCD device");
1163
 
1164
  status = p[1];
1165
  error_code = p[2];
1166
 
1167
  if (error_code != 0)
1168
    {
1169
      sprintf (errbuf, "ocd_do_command (0x%x):", cmd);
1170
      ocd_error (errbuf, error_code);
1171
    }
1172
 
1173
  if (status & OCD_FLAG_PWF)
1174
    error ("OCD device can't detect VCC at BDM interface.");
1175
  else if (status & OCD_FLAG_CABLE_DISC)
1176
    error ("BDM cable appears to be disconnected.");
1177
 
1178
  *statusp = status;
1179
 
1180
  logbuf[0] = OCD_LOG_FILE;
1181
  logbuf[1] = 3;                /* close existing WIGGLERS.LOG */
1182
  ocd_put_packet (logbuf, 2);
1183
  ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
1184
 
1185
  logbuf[0] = OCD_LOG_FILE;
1186
  logbuf[1] = 2;                /* append to existing WIGGLERS.LOG */
1187
  ocd_put_packet (logbuf, 2);
1188
  ocd_get_packet (logbuf[0], &logpktlen, remote_timeout);
1189
 
1190
  return p + 3;
1191
}
1192
 
1193
void
1194
ocd_kill (void)
1195
{
1196
  /* For some mysterious reason, wait_for_inferior calls kill instead of
1197
     mourn after it gets TARGET_WAITKIND_SIGNALLED.  Work around it.  */
1198
  if (kill_kludge)
1199
    {
1200
      kill_kludge = 0;
1201
      target_mourn_inferior ();
1202
      return;
1203
    }
1204
 
1205
  /* Don't wait for it to die.  I'm not really sure it matters whether
1206
     we do or not.  */
1207
  target_mourn_inferior ();
1208
}
1209
 
1210
void
1211
ocd_mourn (void)
1212
{
1213
  unpush_target (current_ops);
1214
  generic_mourn_inferior ();
1215
}
1216
 
1217
/* All we actually do is set the PC to the start address of exec_bfd, and start
1218
   the program at that point.  */
1219
 
1220
void
1221
ocd_create_inferior (char *exec_file, char *args, char **env)
1222
{
1223
  if (args && (*args != '\000'))
1224
    error ("Args are not supported by BDM.");
1225
 
1226
  clear_proceed_status ();
1227
  proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
1228
}
1229
 
1230
void
1231
ocd_load (char *args, int from_tty)
1232
{
1233
  generic_load (args, from_tty);
1234
 
1235
  inferior_ptid = null_ptid;
1236
 
1237
/* This is necessary because many things were based on the PC at the time that
1238
   we attached to the monitor, which is no longer valid now that we have loaded
1239
   new code (and just changed the PC).  Another way to do this might be to call
1240
   normal_stop, except that the stack may not be valid, and things would get
1241
   horribly confused... */
1242
 
1243
  clear_symtab_users ();
1244
}
1245
 
1246
/* This should be defined for each target */
1247
/* But we want to be able to compile this file for some configurations
1248
   not yet supported fully */
1249
 
1250
#define BDM_BREAKPOINT {0x0,0x0,0x0,0x0}        /* For ppc 8xx */
1251
#if 0
1252
#define BDM_BREAKPOINT {0x4a,0xfa}      /* BGND insn used for CPU32 */
1253
#endif
1254
 
1255
/* BDM (at least on CPU32) uses a different breakpoint */
1256
 
1257
int
1258
ocd_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
1259
{
1260
  static char break_insn[] = BDM_BREAKPOINT;
1261
  int val;
1262
 
1263
  val = target_read_memory (addr, contents_cache, sizeof (break_insn));
1264
 
1265
  if (val == 0)
1266
    val = target_write_memory (addr, break_insn, sizeof (break_insn));
1267
 
1268
  return val;
1269
}
1270
 
1271
int
1272
ocd_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
1273
{
1274
  static char break_insn[] = BDM_BREAKPOINT;
1275
  int val;
1276
 
1277
  val = target_write_memory (addr, contents_cache, sizeof (break_insn));
1278
 
1279
  return val;
1280
}
1281
 
1282
static void
1283
bdm_command (char *args, int from_tty)
1284
{
1285
  error ("bdm command must be followed by `reset'");
1286
}
1287
 
1288
static void
1289
bdm_reset_command (char *args, int from_tty)
1290
{
1291
  int status, pktlen;
1292
 
1293
  if (!ocd_desc)
1294
    error ("Not connected to OCD device.");
1295
 
1296
  ocd_do_command (OCD_RESET, &status, &pktlen);
1297
  dcache_invalidate (target_dcache);
1298
  registers_changed ();
1299
}
1300
 
1301
static void
1302
bdm_restart_command (char *args, int from_tty)
1303
{
1304
  int status, pktlen;
1305
 
1306
  if (!ocd_desc)
1307
    error ("Not connected to OCD device.");
1308
 
1309
  ocd_do_command (OCD_RESET_RUN, &status, &pktlen);
1310
  last_run_status = status;
1311
  clear_proceed_status ();
1312
  wait_for_inferior ();
1313
  normal_stop ();
1314
}
1315
 
1316
/* Temporary replacement for target_store_registers().  This prevents
1317
   generic_load from trying to set the PC.  */
1318
 
1319
static void
1320
noop_store_registers (int regno)
1321
{
1322
}
1323
 
1324
static void
1325
bdm_update_flash_command (char *args, int from_tty)
1326
{
1327
  int status, pktlen;
1328
  struct cleanup *old_chain;
1329
  void (*store_registers_tmp) (int);
1330
 
1331
  if (!ocd_desc)
1332
    error ("Not connected to OCD device.");
1333
 
1334
  if (!args)
1335
    error ("Must specify file containing new OCD code.");
1336
 
1337
/*  old_chain = make_cleanup (flash_cleanup, 0); */
1338
 
1339
  ocd_do_command (OCD_ENTER_MON, &status, &pktlen);
1340
 
1341
  ocd_do_command (OCD_ERASE_FLASH, &status, &pktlen);
1342
 
1343
  write_mem_command = OCD_PROGRAM_FLASH;
1344
  store_registers_tmp = current_target.to_store_registers;
1345
  current_target.to_store_registers = noop_store_registers;
1346
 
1347
  generic_load (args, from_tty);
1348
 
1349
  current_target.to_store_registers = store_registers_tmp;
1350
  write_mem_command = OCD_WRITE_MEM;
1351
 
1352
  ocd_do_command (OCD_EXIT_MON, &status, &pktlen);
1353
 
1354
/*  discard_cleanups (old_chain); */
1355
}
1356
 
1357
static void
1358
bdm_read_register_command (char *args, int from_tty)
1359
{
1360
  /* XXX repeat should go on to the next register */
1361
 
1362
  if (!ocd_desc)
1363
    error ("Not connected to OCD device.");
1364
 
1365
  if (!args)
1366
    error ("Must specify BDM register number.");
1367
 
1368
}
1369
 
1370
void
1371
_initialize_remote_ocd (void)
1372
{
1373
  extern struct cmd_list_element *cmdlist;
1374
  static struct cmd_list_element *ocd_cmd_list = NULL;
1375
 
1376
  add_show_from_set (add_set_cmd ("remotetimeout", no_class,
1377
                                  var_integer, (char *) &remote_timeout,
1378
                          "Set timeout value for remote read.\n", &setlist),
1379
                     &showlist);
1380
 
1381
  add_prefix_cmd ("ocd", class_obscure, bdm_command, "", &ocd_cmd_list, "ocd ",
1382
                  0, &cmdlist);
1383
 
1384
  add_cmd ("reset", class_obscure, bdm_reset_command, "", &ocd_cmd_list);
1385
  add_cmd ("restart", class_obscure, bdm_restart_command, "", &ocd_cmd_list);
1386
  add_cmd ("update-flash", class_obscure, bdm_update_flash_command, "", &ocd_cmd_list);
1387
  /*  add_cmd ("read-register", class_obscure, bdm_read_register_command, "", &ocd_cmd_list); */
1388
}

powered by: WebSVN 2.1.0

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