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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [ocd.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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