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