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