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