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